* [PATCH v2 0/3] LoongArch: KVM: Add paravirt preempt support
@ 2025-11-24 3:53 Bibo Mao
2025-11-24 3:53 ` [PATCH v2 1/3] LoongArch: KVM: Add paravirt preempt feature in hypervisor side Bibo Mao
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Bibo Mao @ 2025-11-24 3:53 UTC (permalink / raw)
To: Paolo Bonzini, Huacai Chen; +Cc: kvm, loongarch, linux-kernel
vCPU preempt hint is useful with sched and lock on some platforms, here
new feature KVM_FEATURE_PREEMPT_HINT is added and VMM can selectively
enable it.
Test case kcbench is used to compile Linux kernel code, the test result
shows that it is useful on 3D6000 Dual-way machine with 64 cores and 128
hyperthreads, however no improvemet on 3C5000 Dual-way machine with 32
cores. With perf top command when running test case, the main difference
between over-commited VM and host is osq_lock(). if vcpu_is_preempted()
is implemented on VM, it can avoid unnecessary busy-loop waiting and
enter sleep state quickly if lock-hold vCPU is preempted.
Here is test result with kcbench on 3D6000 and 3C6000 hardware machines,
time unit is second to compile kernel with defconfig, performance is
better with smaller value.
3D6000 Dual-way 64 Core 128 Threads
One VM with 128 vCPUs, no overcommit, NUMA
Orginal With-patch Improvement
VM 91.72 92.4 < -1%
Host 89.7 89.75 < -0.1%
Two VMs overcommit with 128 vCPUs, UMA
Orginal With-patch Improvement
VM1 306.9 197.5 36%
VM2 303.7 197.8 35%
Host 89.7 89.75 < -0.1%
Two VMs overcommit with 128 vCPUs, NUMA
Orginal With-patch Improvement
VM1 317.1 159 50%
VM2 317.5 158 50%
Host 89.7 89.75 < -0.1%
3C5000 Dual-way 32 Core
One VM with 32 vCPUs, NUMA
Orginal With-patch Improvement
VM 208 207 < 0.5%
Host 184 185 < -0.5%
Two VMs overcommit with 32 vCPUs, UMA
Orginal With-patch Improvement
VM1 439 444 -1%
VM2 437 438 < -0.2%
Host 184 185 < -0.5%
Two VMs overcommit with 32 vCPUs, NUMA
Orginal With-patch Improvement
VM1 422 425 < -1%
VM2 418 415 < -1%
Host 184 185 < -0.5%
---
v1 ... v2:
1. Rename feature KVM_FEATURE_PREEMPT_HINT with KVM_FEATURE_PREEMPT,
remove HINT in feature name.
2. Rename reverve field with __u8 pad[47] rather than combination of
__u8 u8_pad[3] and __u32 pad[11]
3. Rename internal function _kvm_set_vcpu_preempted() with
kvm_vcpu_set_pv_preempted(), remove prefix "_" and also in order to
avoid duplication name with common API in future.
4. Remove static variable u8 preempted and macro KVM_VCPU_PREEMPTED is
used directly.
5. Move definition of vcpu_is_preempted() from file spinlock.h to
qspinlock.h, since CONFIG_PARAVIRT is used in qspinlock.h already.
6. Add CONFIG_SMP checking with vcpu_is_preempted() to solve compile
issue reported by LKP if CONFIG_SMP is disabled.
7. Add static key virt_preempt_key with vcpu_is_preempted(), remove
mp_ops.vcpu_is_preempted method.
---
Bibo Mao (3):
LoongArch: KVM: Add paravirt preempt feature in hypervisor side
LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
LoongArch: Add paravirt preempt print prompt
arch/loongarch/include/asm/kvm_host.h | 2 +
arch/loongarch/include/asm/kvm_para.h | 4 +-
arch/loongarch/include/asm/qspinlock.h | 5 ++
arch/loongarch/include/uapi/asm/kvm.h | 1 +
arch/loongarch/include/uapi/asm/kvm_para.h | 1 +
arch/loongarch/kernel/paravirt.c | 24 +++++++++-
arch/loongarch/kvm/vcpu.c | 53 +++++++++++++++++++++-
arch/loongarch/kvm/vm.c | 5 +-
8 files changed, 91 insertions(+), 4 deletions(-)
base-commit: ac3fd01e4c1efce8f2c054cdeb2ddd2fc0fb150d
--
2.39.3
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 1/3] LoongArch: KVM: Add paravirt preempt feature in hypervisor side
2025-11-24 3:53 [PATCH v2 0/3] LoongArch: KVM: Add paravirt preempt support Bibo Mao
@ 2025-11-24 3:53 ` Bibo Mao
2025-11-24 3:54 ` [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side Bibo Mao
2025-11-24 3:54 ` [PATCH v2 3/3] LoongArch: Add paravirt preempt print prompt Bibo Mao
2 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-11-24 3:53 UTC (permalink / raw)
To: Paolo Bonzini, Huacai Chen, Tianrui Zhao, WANG Xuerui
Cc: kvm, loongarch, linux-kernel
Feature KVM_FEATURE_PREEMPT is added to show whether vCPU is preempted
or not. It is to help guest OS scheduling or lock checking etc. Here
add KVM_FEATURE_PREEMPT feature and use one byte as preempted flag in
steal time structure.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/include/asm/kvm_host.h | 2 +
arch/loongarch/include/asm/kvm_para.h | 4 +-
arch/loongarch/include/uapi/asm/kvm.h | 1 +
arch/loongarch/include/uapi/asm/kvm_para.h | 1 +
arch/loongarch/kvm/vcpu.c | 53 +++++++++++++++++++++-
arch/loongarch/kvm/vm.c | 5 +-
6 files changed, 63 insertions(+), 3 deletions(-)
diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
index 0cecbd038bb3..b9ccbeab7fe2 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -162,6 +162,7 @@ enum emulation_result {
#define LOONGARCH_PV_FEAT_UPDATED BIT_ULL(63)
#define LOONGARCH_PV_FEAT_MASK (BIT(KVM_FEATURE_IPI) | \
+ BIT(KVM_FEATURE_PREEMPT) | \
BIT(KVM_FEATURE_STEAL_TIME) | \
BIT(KVM_FEATURE_USER_HCALL) | \
BIT(KVM_FEATURE_VIRT_EXTIOI))
@@ -250,6 +251,7 @@ struct kvm_vcpu_arch {
u64 guest_addr;
u64 last_steal;
struct gfn_to_hva_cache cache;
+ u8 preempted;
} st;
};
diff --git a/arch/loongarch/include/asm/kvm_para.h b/arch/loongarch/include/asm/kvm_para.h
index 3e4b397f423f..fb17ba0fa101 100644
--- a/arch/loongarch/include/asm/kvm_para.h
+++ b/arch/loongarch/include/asm/kvm_para.h
@@ -37,8 +37,10 @@ struct kvm_steal_time {
__u64 steal;
__u32 version;
__u32 flags;
- __u32 pad[12];
+ __u8 preempted;
+ __u8 pad[47];
};
+#define KVM_VCPU_PREEMPTED (1 << 0)
/*
* Hypercall interface for KVM hypervisor
diff --git a/arch/loongarch/include/uapi/asm/kvm.h b/arch/loongarch/include/uapi/asm/kvm.h
index 57ba1a563bb1..71f42c7da322 100644
--- a/arch/loongarch/include/uapi/asm/kvm.h
+++ b/arch/loongarch/include/uapi/asm/kvm.h
@@ -104,6 +104,7 @@ struct kvm_fpu {
#define KVM_LOONGARCH_VM_FEAT_PV_IPI 6
#define KVM_LOONGARCH_VM_FEAT_PV_STEALTIME 7
#define KVM_LOONGARCH_VM_FEAT_PTW 8
+#define KVM_LOONGARCH_VM_FEAT_PV_PREEMPT 10
/* Device Control API on vcpu fd */
#define KVM_LOONGARCH_VCPU_CPUCFG 0
diff --git a/arch/loongarch/include/uapi/asm/kvm_para.h b/arch/loongarch/include/uapi/asm/kvm_para.h
index 76d802ef01ce..d28cbcadd276 100644
--- a/arch/loongarch/include/uapi/asm/kvm_para.h
+++ b/arch/loongarch/include/uapi/asm/kvm_para.h
@@ -15,6 +15,7 @@
#define CPUCFG_KVM_FEATURE (CPUCFG_KVM_BASE + 4)
#define KVM_FEATURE_IPI 1
#define KVM_FEATURE_STEAL_TIME 2
+#define KVM_FEATURE_PREEMPT 3
/* BIT 24 - 31 are features configurable by user space vmm */
#define KVM_FEATURE_VIRT_EXTIOI 24
#define KVM_FEATURE_USER_HCALL 25
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 1245a6b35896..51c14ab96d79 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -180,6 +180,11 @@ static void kvm_update_stolen_time(struct kvm_vcpu *vcpu)
}
st = (struct kvm_steal_time __user *)ghc->hva;
+ if (kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_PREEMPT)) {
+ unsafe_put_user(0, &st->preempted, out);
+ vcpu->arch.st.preempted = 0;
+ }
+
unsafe_get_user(version, &st->version, out);
if (version & 1)
version += 1; /* first time write, random junk */
@@ -1757,11 +1762,57 @@ static int _kvm_vcpu_put(struct kvm_vcpu *vcpu, int cpu)
return 0;
}
+static void kvm_vcpu_set_pv_preempted(struct kvm_vcpu *vcpu)
+{
+ struct gfn_to_hva_cache *ghc;
+ struct kvm_steal_time __user *st;
+ struct kvm_memslots *slots;
+ gpa_t gpa;
+
+ gpa = vcpu->arch.st.guest_addr;
+ if (!(gpa & KVM_STEAL_PHYS_VALID))
+ return;
+
+ /* vCPU may be preempted for many times */
+ if (vcpu->arch.st.preempted)
+ return;
+
+ /* This happens on process exit */
+ if (unlikely(current->mm != vcpu->kvm->mm))
+ return;
+
+ gpa &= KVM_STEAL_PHYS_MASK;
+ ghc = &vcpu->arch.st.cache;
+ slots = kvm_memslots(vcpu->kvm);
+ if (slots->generation != ghc->generation || gpa != ghc->gpa) {
+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gpa, sizeof(*st))) {
+ ghc->gpa = INVALID_GPA;
+ return;
+ }
+ }
+
+ st = (struct kvm_steal_time __user *)ghc->hva;
+ unsafe_put_user(KVM_VCPU_PREEMPTED, &st->preempted, out);
+ vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED;
+out:
+ mark_page_dirty_in_slot(vcpu->kvm, ghc->memslot, gpa_to_gfn(ghc->gpa));
+}
+
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
{
- int cpu;
+ int cpu, idx;
unsigned long flags;
+ if (vcpu->preempted && kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_PREEMPT)) {
+ /*
+ * Take the srcu lock as memslots will be accessed to check the gfn
+ * cache generation against the memslots generation.
+ */
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
+ kvm_vcpu_set_pv_preempted(vcpu);
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
+ }
+
local_irq_save(flags);
cpu = smp_processor_id();
vcpu->arch.last_sched_cpu = cpu;
diff --git a/arch/loongarch/kvm/vm.c b/arch/loongarch/kvm/vm.c
index a49b1c1a3dd1..82115d878481 100644
--- a/arch/loongarch/kvm/vm.c
+++ b/arch/loongarch/kvm/vm.c
@@ -45,8 +45,10 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
/* Enable all PV features by default */
kvm->arch.pv_features = BIT(KVM_FEATURE_IPI);
- if (kvm_pvtime_supported())
+ if (kvm_pvtime_supported()) {
kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME);
+ kvm->arch.pv_features |= BIT(KVM_FEATURE_PREEMPT);
+ }
/*
* cpu_vabits means user address space only (a half of total).
@@ -143,6 +145,7 @@ static int kvm_vm_feature_has_attr(struct kvm *kvm, struct kvm_device_attr *attr
case KVM_LOONGARCH_VM_FEAT_PV_IPI:
return 0;
case KVM_LOONGARCH_VM_FEAT_PV_STEALTIME:
+ case KVM_LOONGARCH_VM_FEAT_PV_PREEMPT:
if (kvm_pvtime_supported())
return 0;
return -ENXIO;
--
2.39.3
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 3:53 [PATCH v2 0/3] LoongArch: KVM: Add paravirt preempt support Bibo Mao
2025-11-24 3:53 ` [PATCH v2 1/3] LoongArch: KVM: Add paravirt preempt feature in hypervisor side Bibo Mao
@ 2025-11-24 3:54 ` Bibo Mao
2025-11-24 6:33 ` Huacai Chen
2025-11-24 3:54 ` [PATCH v2 3/3] LoongArch: Add paravirt preempt print prompt Bibo Mao
2 siblings, 1 reply; 16+ messages in thread
From: Bibo Mao @ 2025-11-24 3:54 UTC (permalink / raw)
To: Paolo Bonzini, Huacai Chen, WANG Xuerui, Juergen Gross,
Ajay Kaher, Alexey Makhalov,
Broadcom internal kernel review list
Cc: kvm, loongarch, linux-kernel, virtualization, x86
Function vcpu_is_preempted() is used to check whether vCPU is preempted
or not. Here add implementation with vcpu_is_preempted() when option
CONFIG_PARAVIRT is enabled.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/include/asm/qspinlock.h | 5 +++++
arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
index e76d3aa1e1eb..9a5b7ba1f4cb 100644
--- a/arch/loongarch/include/asm/qspinlock.h
+++ b/arch/loongarch/include/asm/qspinlock.h
@@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
return true;
}
+#ifdef CONFIG_SMP
+#define vcpu_is_preempted vcpu_is_preempted
+bool vcpu_is_preempted(int cpu);
+#endif
+
#endif /* CONFIG_PARAVIRT */
#include <asm-generic/qspinlock.h>
diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
index b1b51f920b23..d4163679adc4 100644
--- a/arch/loongarch/kernel/paravirt.c
+++ b/arch/loongarch/kernel/paravirt.c
@@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
}
#ifdef CONFIG_SMP
+DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
static int pv_time_cpu_online(unsigned int cpu)
{
unsigned long flags;
@@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
return 0;
}
+
+bool notrace vcpu_is_preempted(int cpu)
+{
+ struct kvm_steal_time *src;
+
+ if (!static_branch_unlikely(&virt_preempt_key))
+ return false;
+
+ src = &per_cpu(steal_time, cpu);
+ return !!(src->preempted & KVM_VCPU_PREEMPTED);
+}
+EXPORT_SYMBOL(vcpu_is_preempted);
#endif
static void pv_cpu_reboot(void *unused)
@@ -308,6 +321,9 @@ int __init pv_time_init(void)
pr_err("Failed to install cpu hotplug callbacks\n");
return r;
}
+
+ if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
+ static_branch_enable(&virt_preempt_key);
#endif
static_call_update(pv_steal_clock, paravt_steal_clock);
--
2.39.3
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 3/3] LoongArch: Add paravirt preempt print prompt
2025-11-24 3:53 [PATCH v2 0/3] LoongArch: KVM: Add paravirt preempt support Bibo Mao
2025-11-24 3:53 ` [PATCH v2 1/3] LoongArch: KVM: Add paravirt preempt feature in hypervisor side Bibo Mao
2025-11-24 3:54 ` [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side Bibo Mao
@ 2025-11-24 3:54 ` Bibo Mao
2025-11-24 6:33 ` Huacai Chen
2 siblings, 1 reply; 16+ messages in thread
From: Bibo Mao @ 2025-11-24 3:54 UTC (permalink / raw)
To: Paolo Bonzini, Huacai Chen, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list,
WANG Xuerui
Cc: kvm, loongarch, linux-kernel, virtualization, x86
Add paravirt preempt print prompt together with steal timer information,
so that it is easy to check whether paravirt preempt feature is enabled
or not.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/kernel/paravirt.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
index d4163679adc4..ffe1cf284c41 100644
--- a/arch/loongarch/kernel/paravirt.c
+++ b/arch/loongarch/kernel/paravirt.c
@@ -300,6 +300,7 @@ static struct notifier_block pv_reboot_nb = {
int __init pv_time_init(void)
{
int r;
+ bool pv_preempted = false;
if (!kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
return 0;
@@ -322,8 +323,10 @@ int __init pv_time_init(void)
return r;
}
- if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
+ if (kvm_para_has_feature(KVM_FEATURE_PREEMPT)) {
static_branch_enable(&virt_preempt_key);
+ pv_preempted = true;
+ }
#endif
static_call_update(pv_steal_clock, paravt_steal_clock);
@@ -334,7 +337,10 @@ int __init pv_time_init(void)
static_key_slow_inc(¶virt_steal_rq_enabled);
#endif
- pr_info("Using paravirt steal-time\n");
+ if (pv_preempted)
+ pr_info("Using paravirt steal-time with preempt hint enabled\n");
+ else
+ pr_info("Using paravirt steal-time with preempt hint disabled\n");
return 0;
}
--
2.39.3
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 3:54 ` [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side Bibo Mao
@ 2025-11-24 6:33 ` Huacai Chen
2025-11-24 6:55 ` Jürgen Groß
2025-11-24 7:00 ` Bibo Mao
0 siblings, 2 replies; 16+ messages in thread
From: Huacai Chen @ 2025-11-24 6:33 UTC (permalink / raw)
To: Bibo Mao
Cc: Paolo Bonzini, WANG Xuerui, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list, kvm,
loongarch, linux-kernel, virtualization, x86
Hi, Bibo,
On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
>
> Function vcpu_is_preempted() is used to check whether vCPU is preempted
> or not. Here add implementation with vcpu_is_preempted() when option
> CONFIG_PARAVIRT is enabled.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> arch/loongarch/include/asm/qspinlock.h | 5 +++++
> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
> 2 files changed, 21 insertions(+)
>
> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
> --- a/arch/loongarch/include/asm/qspinlock.h
> +++ b/arch/loongarch/include/asm/qspinlock.h
> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
> return true;
> }
>
> +#ifdef CONFIG_SMP
> +#define vcpu_is_preempted vcpu_is_preempted
> +bool vcpu_is_preempted(int cpu);
In V1 there is a build error because you reference mp_ops, so in V2
you needn't put it in CONFIG_SMP.
On the other hand, even if you really build a UP guest kernel, when
multiple guests run together, you probably need vcpu_is_preemtped.
Huacai
> +#endif
> +
> #endif /* CONFIG_PARAVIRT */
>
> #include <asm-generic/qspinlock.h>
> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
> index b1b51f920b23..d4163679adc4 100644
> --- a/arch/loongarch/kernel/paravirt.c
> +++ b/arch/loongarch/kernel/paravirt.c
> @@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
> }
>
> #ifdef CONFIG_SMP
> +DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
> static int pv_time_cpu_online(unsigned int cpu)
> {
> unsigned long flags;
> @@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
>
> return 0;
> }
> +
> +bool notrace vcpu_is_preempted(int cpu)
> +{
> + struct kvm_steal_time *src;
> +
> + if (!static_branch_unlikely(&virt_preempt_key))
> + return false;
> +
> + src = &per_cpu(steal_time, cpu);
> + return !!(src->preempted & KVM_VCPU_PREEMPTED);
> +}
> +EXPORT_SYMBOL(vcpu_is_preempted);
> #endif
>
> static void pv_cpu_reboot(void *unused)
> @@ -308,6 +321,9 @@ int __init pv_time_init(void)
> pr_err("Failed to install cpu hotplug callbacks\n");
> return r;
> }
> +
> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
> + static_branch_enable(&virt_preempt_key);
> #endif
>
> static_call_update(pv_steal_clock, paravt_steal_clock);
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 3/3] LoongArch: Add paravirt preempt print prompt
2025-11-24 3:54 ` [PATCH v2 3/3] LoongArch: Add paravirt preempt print prompt Bibo Mao
@ 2025-11-24 6:33 ` Huacai Chen
2025-11-24 7:10 ` Bibo Mao
0 siblings, 1 reply; 16+ messages in thread
From: Huacai Chen @ 2025-11-24 6:33 UTC (permalink / raw)
To: Bibo Mao
Cc: Paolo Bonzini, Juergen Gross, Ajay Kaher, Alexey Makhalov,
Broadcom internal kernel review list, WANG Xuerui, kvm,
loongarch, linux-kernel, virtualization, x86
Hi, Bibo,
On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
>
> Add paravirt preempt print prompt together with steal timer information,
> so that it is easy to check whether paravirt preempt feature is enabled
> or not.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> arch/loongarch/kernel/paravirt.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
> index d4163679adc4..ffe1cf284c41 100644
> --- a/arch/loongarch/kernel/paravirt.c
> +++ b/arch/loongarch/kernel/paravirt.c
> @@ -300,6 +300,7 @@ static struct notifier_block pv_reboot_nb = {
> int __init pv_time_init(void)
> {
> int r;
> + bool pv_preempted = false;
>
> if (!kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
> return 0;
> @@ -322,8 +323,10 @@ int __init pv_time_init(void)
> return r;
> }
>
> - if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT)) {
> static_branch_enable(&virt_preempt_key);
> + pv_preempted = true;
> + }
> #endif
>
> static_call_update(pv_steal_clock, paravt_steal_clock);
> @@ -334,7 +337,10 @@ int __init pv_time_init(void)
> static_key_slow_inc(¶virt_steal_rq_enabled);
> #endif
>
> - pr_info("Using paravirt steal-time\n");
> + if (pv_preempted)
No pv_preempted needed, you can just use
static_key_enabled(&virt_preempt_key) and merge this patch to Patch-2.
Huacai
> + pr_info("Using paravirt steal-time with preempt hint enabled\n");
> + else
> + pr_info("Using paravirt steal-time with preempt hint disabled\n");
>
> return 0;
> }
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 6:33 ` Huacai Chen
@ 2025-11-24 6:55 ` Jürgen Groß
2025-11-24 7:00 ` Bibo Mao
1 sibling, 0 replies; 16+ messages in thread
From: Jürgen Groß @ 2025-11-24 6:55 UTC (permalink / raw)
To: Huacai Chen, Bibo Mao
Cc: Paolo Bonzini, WANG Xuerui, Ajay Kaher, Alexey Makhalov,
Broadcom internal kernel review list, kvm, loongarch,
linux-kernel, virtualization, x86
[-- Attachment #1.1.1: Type: text/plain, Size: 1370 bytes --]
On 24.11.25 07:33, Huacai Chen wrote:
> Hi, Bibo,
>
> On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>> Function vcpu_is_preempted() is used to check whether vCPU is preempted
>> or not. Here add implementation with vcpu_is_preempted() when option
>> CONFIG_PARAVIRT is enabled.
>>
>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>> ---
>> arch/loongarch/include/asm/qspinlock.h | 5 +++++
>> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
>> 2 files changed, 21 insertions(+)
>>
>> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
>> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
>> --- a/arch/loongarch/include/asm/qspinlock.h
>> +++ b/arch/loongarch/include/asm/qspinlock.h
>> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
>> return true;
>> }
>>
>> +#ifdef CONFIG_SMP
>> +#define vcpu_is_preempted vcpu_is_preempted
>> +bool vcpu_is_preempted(int cpu);
> In V1 there is a build error because you reference mp_ops, so in V2
> you needn't put it in CONFIG_SMP.
> On the other hand, even if you really build a UP guest kernel, when
> multiple guests run together, you probably need vcpu_is_preemtped.
I don't think so. When the UP guest's vcpu is preempted, who will use this
function?
Juergen
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 6:33 ` Huacai Chen
2025-11-24 6:55 ` Jürgen Groß
@ 2025-11-24 7:00 ` Bibo Mao
2025-11-24 7:13 ` Huacai Chen
1 sibling, 1 reply; 16+ messages in thread
From: Bibo Mao @ 2025-11-24 7:00 UTC (permalink / raw)
To: Huacai Chen
Cc: Paolo Bonzini, WANG Xuerui, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list, kvm,
loongarch, linux-kernel, virtualization, x86
On 2025/11/24 下午2:33, Huacai Chen wrote:
> Hi, Bibo,
>
> On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>> Function vcpu_is_preempted() is used to check whether vCPU is preempted
>> or not. Here add implementation with vcpu_is_preempted() when option
>> CONFIG_PARAVIRT is enabled.
>>
>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>> ---
>> arch/loongarch/include/asm/qspinlock.h | 5 +++++
>> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
>> 2 files changed, 21 insertions(+)
>>
>> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
>> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
>> --- a/arch/loongarch/include/asm/qspinlock.h
>> +++ b/arch/loongarch/include/asm/qspinlock.h
>> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
>> return true;
>> }
>>
>> +#ifdef CONFIG_SMP
>> +#define vcpu_is_preempted vcpu_is_preempted
>> +bool vcpu_is_preempted(int cpu);
> In V1 there is a build error because you reference mp_ops, so in V2
> you needn't put it in CONFIG_SMP.
The compile failure problem is that vcpu_is_preempted() is redefined in
both arch/loongarch/kernel/paravirt.c and include/linux/sched.h
The problem is that <asm/spinlock.h> is not included by sched.h, if
CONFIG_SMP is disabled. Here is part of file include/linux/spinlock.h
#ifdef CONFIG_SMP
# include <asm/spinlock.h>
#else
# include <linux/spinlock_up.h>
#endif
> On the other hand, even if you really build a UP guest kernel, when
> multiple guests run together, you probably need vcpu_is_preemtped.
It is not relative with multiple VMs. When vcpu_is_preempted() is
called, it is to detect whether dest CPU is preempted or not, the cpu
from smp_processor_id() should not be preempted. So in generic
vcpu_is_preempted() works on multiple vCPUs.
Regards
Bibo Mao
>
>
> Huacai
>
>> +#endif
>> +
>> #endif /* CONFIG_PARAVIRT */
>>
>> #include <asm-generic/qspinlock.h>
>> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
>> index b1b51f920b23..d4163679adc4 100644
>> --- a/arch/loongarch/kernel/paravirt.c
>> +++ b/arch/loongarch/kernel/paravirt.c
>> @@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
>> }
>>
>> #ifdef CONFIG_SMP
>> +DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
>> static int pv_time_cpu_online(unsigned int cpu)
>> {
>> unsigned long flags;
>> @@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
>>
>> return 0;
>> }
>> +
>> +bool notrace vcpu_is_preempted(int cpu)
>> +{
>> + struct kvm_steal_time *src;
>> +
>> + if (!static_branch_unlikely(&virt_preempt_key))
>> + return false;
>> +
>> + src = &per_cpu(steal_time, cpu);
>> + return !!(src->preempted & KVM_VCPU_PREEMPTED);
>> +}
>> +EXPORT_SYMBOL(vcpu_is_preempted);
>> #endif
>>
>> static void pv_cpu_reboot(void *unused)
>> @@ -308,6 +321,9 @@ int __init pv_time_init(void)
>> pr_err("Failed to install cpu hotplug callbacks\n");
>> return r;
>> }
>> +
>> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
>> + static_branch_enable(&virt_preempt_key);
>> #endif
>>
>> static_call_update(pv_steal_clock, paravt_steal_clock);
>> --
>> 2.39.3
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 3/3] LoongArch: Add paravirt preempt print prompt
2025-11-24 6:33 ` Huacai Chen
@ 2025-11-24 7:10 ` Bibo Mao
0 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-11-24 7:10 UTC (permalink / raw)
To: Huacai Chen
Cc: Paolo Bonzini, Juergen Gross, Ajay Kaher, Alexey Makhalov,
Broadcom internal kernel review list, WANG Xuerui, kvm,
loongarch, linux-kernel, virtualization, x86
On 2025/11/24 下午2:33, Huacai Chen wrote:
> Hi, Bibo,
>
> On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>> Add paravirt preempt print prompt together with steal timer information,
>> so that it is easy to check whether paravirt preempt feature is enabled
>> or not.
>>
>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>> ---
>> arch/loongarch/kernel/paravirt.c | 10 ++++++++--
>> 1 file changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
>> index d4163679adc4..ffe1cf284c41 100644
>> --- a/arch/loongarch/kernel/paravirt.c
>> +++ b/arch/loongarch/kernel/paravirt.c
>> @@ -300,6 +300,7 @@ static struct notifier_block pv_reboot_nb = {
>> int __init pv_time_init(void)
>> {
>> int r;
>> + bool pv_preempted = false;
>>
>> if (!kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
>> return 0;
>> @@ -322,8 +323,10 @@ int __init pv_time_init(void)
>> return r;
>> }
>>
>> - if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
>> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT)) {
>> static_branch_enable(&virt_preempt_key);
>> + pv_preempted = true;
>> + }
>> #endif
>>
>> static_call_update(pv_steal_clock, paravt_steal_clock);
>> @@ -334,7 +337,10 @@ int __init pv_time_init(void)
>> static_key_slow_inc(¶virt_steal_rq_enabled);
>> #endif
>>
>> - pr_info("Using paravirt steal-time\n");
>> + if (pv_preempted)
> No pv_preempted needed, you can just use
> static_key_enabled(&virt_preempt_key) and merge this patch to Patch-2.
yes, good idea.
Will do in next version with these two points.
Regards
Bibo Mao
>
>
> Huacai
>
>> + pr_info("Using paravirt steal-time with preempt hint enabled\n");
>> + else
>> + pr_info("Using paravirt steal-time with preempt hint disabled\n");
>>
>> return 0;
>> }
>> --
>> 2.39.3
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 7:00 ` Bibo Mao
@ 2025-11-24 7:13 ` Huacai Chen
2025-11-24 7:48 ` Bibo Mao
0 siblings, 1 reply; 16+ messages in thread
From: Huacai Chen @ 2025-11-24 7:13 UTC (permalink / raw)
To: Bibo Mao
Cc: Paolo Bonzini, WANG Xuerui, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list, kvm,
loongarch, linux-kernel, virtualization, x86
On Mon, Nov 24, 2025 at 3:03 PM Bibo Mao <maobibo@loongson.cn> wrote:
>
>
>
> On 2025/11/24 下午2:33, Huacai Chen wrote:
> > Hi, Bibo,
> >
> > On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
> >>
> >> Function vcpu_is_preempted() is used to check whether vCPU is preempted
> >> or not. Here add implementation with vcpu_is_preempted() when option
> >> CONFIG_PARAVIRT is enabled.
> >>
> >> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> >> ---
> >> arch/loongarch/include/asm/qspinlock.h | 5 +++++
> >> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
> >> 2 files changed, 21 insertions(+)
> >>
> >> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
> >> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
> >> --- a/arch/loongarch/include/asm/qspinlock.h
> >> +++ b/arch/loongarch/include/asm/qspinlock.h
> >> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
> >> return true;
> >> }
> >>
> >> +#ifdef CONFIG_SMP
> >> +#define vcpu_is_preempted vcpu_is_preempted
> >> +bool vcpu_is_preempted(int cpu);
> > In V1 there is a build error because you reference mp_ops, so in V2
> > you needn't put it in CONFIG_SMP.
> The compile failure problem is that vcpu_is_preempted() is redefined in
> both arch/loongarch/kernel/paravirt.c and include/linux/sched.h
But other archs don't define vcpu_is_preempted() under CONFIG_SMP, and
you can consider to inline the whole vcpu_is_preempted() here.
>
> The problem is that <asm/spinlock.h> is not included by sched.h, if
> CONFIG_SMP is disabled. Here is part of file include/linux/spinlock.h
> #ifdef CONFIG_SMP
> # include <asm/spinlock.h>
> #else
> # include <linux/spinlock_up.h>
> #endif
>
> > On the other hand, even if you really build a UP guest kernel, when
> > multiple guests run together, you probably need vcpu_is_preemtped.
> It is not relative with multiple VMs. When vcpu_is_preempted() is
> called, it is to detect whether dest CPU is preempted or not, the cpu
> from smp_processor_id() should not be preempted. So in generic
> vcpu_is_preempted() works on multiple vCPUs.
OK, I'm wrong here.
Huacai
>
> Regards
> Bibo Mao
> >
> >
> > Huacai
> >
> >> +#endif
> >> +
> >> #endif /* CONFIG_PARAVIRT */
> >>
> >> #include <asm-generic/qspinlock.h>
> >> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
> >> index b1b51f920b23..d4163679adc4 100644
> >> --- a/arch/loongarch/kernel/paravirt.c
> >> +++ b/arch/loongarch/kernel/paravirt.c
> >> @@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
> >> }
> >>
> >> #ifdef CONFIG_SMP
> >> +DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
> >> static int pv_time_cpu_online(unsigned int cpu)
> >> {
> >> unsigned long flags;
> >> @@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
> >>
> >> return 0;
> >> }
> >> +
> >> +bool notrace vcpu_is_preempted(int cpu)
> >> +{
> >> + struct kvm_steal_time *src;
> >> +
> >> + if (!static_branch_unlikely(&virt_preempt_key))
> >> + return false;
> >> +
> >> + src = &per_cpu(steal_time, cpu);
> >> + return !!(src->preempted & KVM_VCPU_PREEMPTED);
> >> +}
> >> +EXPORT_SYMBOL(vcpu_is_preempted);
> >> #endif
> >>
> >> static void pv_cpu_reboot(void *unused)
> >> @@ -308,6 +321,9 @@ int __init pv_time_init(void)
> >> pr_err("Failed to install cpu hotplug callbacks\n");
> >> return r;
> >> }
> >> +
> >> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
> >> + static_branch_enable(&virt_preempt_key);
> >> #endif
> >>
> >> static_call_update(pv_steal_clock, paravt_steal_clock);
> >> --
> >> 2.39.3
> >>
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 7:13 ` Huacai Chen
@ 2025-11-24 7:48 ` Bibo Mao
2025-11-24 8:03 ` Huacai Chen
0 siblings, 1 reply; 16+ messages in thread
From: Bibo Mao @ 2025-11-24 7:48 UTC (permalink / raw)
To: Huacai Chen
Cc: Paolo Bonzini, WANG Xuerui, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list, kvm,
loongarch, linux-kernel, virtualization, x86
On 2025/11/24 下午3:13, Huacai Chen wrote:
> On Mon, Nov 24, 2025 at 3:03 PM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>>
>>
>> On 2025/11/24 下午2:33, Huacai Chen wrote:
>>> Hi, Bibo,
>>>
>>> On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
>>>>
>>>> Function vcpu_is_preempted() is used to check whether vCPU is preempted
>>>> or not. Here add implementation with vcpu_is_preempted() when option
>>>> CONFIG_PARAVIRT is enabled.
>>>>
>>>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>>>> ---
>>>> arch/loongarch/include/asm/qspinlock.h | 5 +++++
>>>> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
>>>> 2 files changed, 21 insertions(+)
>>>>
>>>> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
>>>> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
>>>> --- a/arch/loongarch/include/asm/qspinlock.h
>>>> +++ b/arch/loongarch/include/asm/qspinlock.h
>>>> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
>>>> return true;
>>>> }
>>>>
>>>> +#ifdef CONFIG_SMP
>>>> +#define vcpu_is_preempted vcpu_is_preempted
>>>> +bool vcpu_is_preempted(int cpu);
>>> In V1 there is a build error because you reference mp_ops, so in V2
>>> you needn't put it in CONFIG_SMP.
>> The compile failure problem is that vcpu_is_preempted() is redefined in
>> both arch/loongarch/kernel/paravirt.c and include/linux/sched.h
> But other archs don't define vcpu_is_preempted() under CONFIG_SMP, and
so what is advantage to implement this function if CONFIG_SMP is disabled?
> you can consider to inline the whole vcpu_is_preempted() here.
Defining the function vcpu_is_preempted() as inlined is not so easy for
me, it beyond my ability now :(
With static key method, the static key need be exported, all modules
need apply the jump label, that is dangerous and I doubt whether it is
deserved.
Regards
Bibo Mao
>
>>
>> The problem is that <asm/spinlock.h> is not included by sched.h, if
>> CONFIG_SMP is disabled. Here is part of file include/linux/spinlock.h
>> #ifdef CONFIG_SMP
>> # include <asm/spinlock.h>
>> #else
>> # include <linux/spinlock_up.h>
>> #endif
>>
>>> On the other hand, even if you really build a UP guest kernel, when
>>> multiple guests run together, you probably need vcpu_is_preemtped.
>> It is not relative with multiple VMs. When vcpu_is_preempted() is
>> called, it is to detect whether dest CPU is preempted or not, the cpu
>> from smp_processor_id() should not be preempted. So in generic
>> vcpu_is_preempted() works on multiple vCPUs.
> OK, I'm wrong here.
>
>
> Huacai
>
>>
>> Regards
>> Bibo Mao
>>>
>>>
>>> Huacai
>>>
>>>> +#endif
>>>> +
>>>> #endif /* CONFIG_PARAVIRT */
>>>>
>>>> #include <asm-generic/qspinlock.h>
>>>> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
>>>> index b1b51f920b23..d4163679adc4 100644
>>>> --- a/arch/loongarch/kernel/paravirt.c
>>>> +++ b/arch/loongarch/kernel/paravirt.c
>>>> @@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
>>>> }
>>>>
>>>> #ifdef CONFIG_SMP
>>>> +DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
>>>> static int pv_time_cpu_online(unsigned int cpu)
>>>> {
>>>> unsigned long flags;
>>>> @@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
>>>>
>>>> return 0;
>>>> }
>>>> +
>>>> +bool notrace vcpu_is_preempted(int cpu)
>>>> +{
>>>> + struct kvm_steal_time *src;
>>>> +
>>>> + if (!static_branch_unlikely(&virt_preempt_key))
>>>> + return false;
>>>> +
>>>> + src = &per_cpu(steal_time, cpu);
>>>> + return !!(src->preempted & KVM_VCPU_PREEMPTED);
>>>> +}
>>>> +EXPORT_SYMBOL(vcpu_is_preempted);
>>>> #endif
>>>>
>>>> static void pv_cpu_reboot(void *unused)
>>>> @@ -308,6 +321,9 @@ int __init pv_time_init(void)
>>>> pr_err("Failed to install cpu hotplug callbacks\n");
>>>> return r;
>>>> }
>>>> +
>>>> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
>>>> + static_branch_enable(&virt_preempt_key);
>>>> #endif
>>>>
>>>> static_call_update(pv_steal_clock, paravt_steal_clock);
>>>> --
>>>> 2.39.3
>>>>
>>
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 7:48 ` Bibo Mao
@ 2025-11-24 8:03 ` Huacai Chen
2025-11-24 8:32 ` Bibo Mao
0 siblings, 1 reply; 16+ messages in thread
From: Huacai Chen @ 2025-11-24 8:03 UTC (permalink / raw)
To: Bibo Mao
Cc: Paolo Bonzini, WANG Xuerui, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list, kvm,
loongarch, linux-kernel, virtualization, x86
On Mon, Nov 24, 2025 at 3:50 PM Bibo Mao <maobibo@loongson.cn> wrote:
>
>
>
> On 2025/11/24 下午3:13, Huacai Chen wrote:
> > On Mon, Nov 24, 2025 at 3:03 PM Bibo Mao <maobibo@loongson.cn> wrote:
> >>
> >>
> >>
> >> On 2025/11/24 下午2:33, Huacai Chen wrote:
> >>> Hi, Bibo,
> >>>
> >>> On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
> >>>>
> >>>> Function vcpu_is_preempted() is used to check whether vCPU is preempted
> >>>> or not. Here add implementation with vcpu_is_preempted() when option
> >>>> CONFIG_PARAVIRT is enabled.
> >>>>
> >>>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> >>>> ---
> >>>> arch/loongarch/include/asm/qspinlock.h | 5 +++++
> >>>> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
> >>>> 2 files changed, 21 insertions(+)
> >>>>
> >>>> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
> >>>> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
> >>>> --- a/arch/loongarch/include/asm/qspinlock.h
> >>>> +++ b/arch/loongarch/include/asm/qspinlock.h
> >>>> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
> >>>> return true;
> >>>> }
> >>>>
> >>>> +#ifdef CONFIG_SMP
> >>>> +#define vcpu_is_preempted vcpu_is_preempted
> >>>> +bool vcpu_is_preempted(int cpu);
> >>> In V1 there is a build error because you reference mp_ops, so in V2
> >>> you needn't put it in CONFIG_SMP.
> >> The compile failure problem is that vcpu_is_preempted() is redefined in
> >> both arch/loongarch/kernel/paravirt.c and include/linux/sched.h
> > But other archs don't define vcpu_is_preempted() under CONFIG_SMP, and
> so what is advantage to implement this function if CONFIG_SMP is disabled?
1. Keep consistency with other architectures.
2. Keep it simple to reduce #ifdefs (and !SMP is just for build, not
very useful in practice).
>
> > you can consider to inline the whole vcpu_is_preempted() here.
> Defining the function vcpu_is_preempted() as inlined is not so easy for
> me, it beyond my ability now :(
>
> With static key method, the static key need be exported, all modules
> need apply the jump label, that is dangerous and I doubt whether it is
> deserved.
No, you have already done similar things in virt_spin_lock(), it is an
inline function and uses virt_spin_lock_key.
Huacai
>
> Regards
> Bibo Mao
> >
> >>
> >> The problem is that <asm/spinlock.h> is not included by sched.h, if
> >> CONFIG_SMP is disabled. Here is part of file include/linux/spinlock.h
> >> #ifdef CONFIG_SMP
> >> # include <asm/spinlock.h>
> >> #else
> >> # include <linux/spinlock_up.h>
> >> #endif
> >>
> >>> On the other hand, even if you really build a UP guest kernel, when
> >>> multiple guests run together, you probably need vcpu_is_preemtped.
> >> It is not relative with multiple VMs. When vcpu_is_preempted() is
> >> called, it is to detect whether dest CPU is preempted or not, the cpu
> >> from smp_processor_id() should not be preempted. So in generic
> >> vcpu_is_preempted() works on multiple vCPUs.
> > OK, I'm wrong here.
> >
> >
> > Huacai
> >
> >>
> >> Regards
> >> Bibo Mao
> >>>
> >>>
> >>> Huacai
> >>>
> >>>> +#endif
> >>>> +
> >>>> #endif /* CONFIG_PARAVIRT */
> >>>>
> >>>> #include <asm-generic/qspinlock.h>
> >>>> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
> >>>> index b1b51f920b23..d4163679adc4 100644
> >>>> --- a/arch/loongarch/kernel/paravirt.c
> >>>> +++ b/arch/loongarch/kernel/paravirt.c
> >>>> @@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
> >>>> }
> >>>>
> >>>> #ifdef CONFIG_SMP
> >>>> +DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
> >>>> static int pv_time_cpu_online(unsigned int cpu)
> >>>> {
> >>>> unsigned long flags;
> >>>> @@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
> >>>>
> >>>> return 0;
> >>>> }
> >>>> +
> >>>> +bool notrace vcpu_is_preempted(int cpu)
> >>>> +{
> >>>> + struct kvm_steal_time *src;
> >>>> +
> >>>> + if (!static_branch_unlikely(&virt_preempt_key))
> >>>> + return false;
> >>>> +
> >>>> + src = &per_cpu(steal_time, cpu);
> >>>> + return !!(src->preempted & KVM_VCPU_PREEMPTED);
> >>>> +}
> >>>> +EXPORT_SYMBOL(vcpu_is_preempted);
> >>>> #endif
> >>>>
> >>>> static void pv_cpu_reboot(void *unused)
> >>>> @@ -308,6 +321,9 @@ int __init pv_time_init(void)
> >>>> pr_err("Failed to install cpu hotplug callbacks\n");
> >>>> return r;
> >>>> }
> >>>> +
> >>>> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
> >>>> + static_branch_enable(&virt_preempt_key);
> >>>> #endif
> >>>>
> >>>> static_call_update(pv_steal_clock, paravt_steal_clock);
> >>>> --
> >>>> 2.39.3
> >>>>
> >>
> >>
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 8:03 ` Huacai Chen
@ 2025-11-24 8:32 ` Bibo Mao
2025-11-24 9:03 ` Huacai Chen
0 siblings, 1 reply; 16+ messages in thread
From: Bibo Mao @ 2025-11-24 8:32 UTC (permalink / raw)
To: Huacai Chen
Cc: Paolo Bonzini, WANG Xuerui, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list, kvm,
loongarch, linux-kernel, virtualization, x86
On 2025/11/24 下午4:03, Huacai Chen wrote:
> On Mon, Nov 24, 2025 at 3:50 PM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>>
>>
>> On 2025/11/24 下午3:13, Huacai Chen wrote:
>>> On Mon, Nov 24, 2025 at 3:03 PM Bibo Mao <maobibo@loongson.cn> wrote:
>>>>
>>>>
>>>>
>>>> On 2025/11/24 下午2:33, Huacai Chen wrote:
>>>>> Hi, Bibo,
>>>>>
>>>>> On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
>>>>>>
>>>>>> Function vcpu_is_preempted() is used to check whether vCPU is preempted
>>>>>> or not. Here add implementation with vcpu_is_preempted() when option
>>>>>> CONFIG_PARAVIRT is enabled.
>>>>>>
>>>>>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>>>>>> ---
>>>>>> arch/loongarch/include/asm/qspinlock.h | 5 +++++
>>>>>> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
>>>>>> 2 files changed, 21 insertions(+)
>>>>>>
>>>>>> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
>>>>>> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
>>>>>> --- a/arch/loongarch/include/asm/qspinlock.h
>>>>>> +++ b/arch/loongarch/include/asm/qspinlock.h
>>>>>> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
>>>>>> return true;
>>>>>> }
>>>>>>
>>>>>> +#ifdef CONFIG_SMP
>>>>>> +#define vcpu_is_preempted vcpu_is_preempted
>>>>>> +bool vcpu_is_preempted(int cpu);
>>>>> In V1 there is a build error because you reference mp_ops, so in V2
>>>>> you needn't put it in CONFIG_SMP.
>>>> The compile failure problem is that vcpu_is_preempted() is redefined in
>>>> both arch/loongarch/kernel/paravirt.c and include/linux/sched.h
>>> But other archs don't define vcpu_is_preempted() under CONFIG_SMP, and
>> so what is advantage to implement this function if CONFIG_SMP is disabled?
> 1. Keep consistency with other architectures.
> 2. Keep it simple to reduce #ifdefs (and !SMP is just for build, not
> very useful in practice).
It seems that CONFIG_SMP can be removed in header file
include/asm/qspinlock.h, since asm/spinlock.h and asm/qspinlock.h is
only included when CONFIG_SMP is set, otherwise only linux/spinlock_up.h
is included.
>
>>
>>> you can consider to inline the whole vcpu_is_preempted() here.
>> Defining the function vcpu_is_preempted() as inlined is not so easy for
>> me, it beyond my ability now :(
>>
>> With static key method, the static key need be exported, all modules
>> need apply the jump label, that is dangerous and I doubt whether it is
>> deserved.
> No, you have already done similar things in virt_spin_lock(), it is an
> inline function and uses virt_spin_lock_key.
virt_spin_lock is only called qspinlock in function
queued_spin_lock_slowpath(). Function vcpu_is_preempted() is defined
header file linux/sched.h, kernel module may use it.
>
> Huacai
>
>>
>> Regards
>> Bibo Mao
>>>
>>>>
>>>> The problem is that <asm/spinlock.h> is not included by sched.h, if
>>>> CONFIG_SMP is disabled. Here is part of file include/linux/spinlock.h
>>>> #ifdef CONFIG_SMP
>>>> # include <asm/spinlock.h>
>>>> #else
>>>> # include <linux/spinlock_up.h>
>>>> #endif
>>>>
>>>>> On the other hand, even if you really build a UP guest kernel, when
>>>>> multiple guests run together, you probably need vcpu_is_preemtped.
>>>> It is not relative with multiple VMs. When vcpu_is_preempted() is
>>>> called, it is to detect whether dest CPU is preempted or not, the cpu
>>>> from smp_processor_id() should not be preempted. So in generic
>>>> vcpu_is_preempted() works on multiple vCPUs.
>>> OK, I'm wrong here.
>>>
>>>
>>> Huacai
>>>
>>>>
>>>> Regards
>>>> Bibo Mao
>>>>>
>>>>>
>>>>> Huacai
>>>>>
>>>>>> +#endif
>>>>>> +
>>>>>> #endif /* CONFIG_PARAVIRT */
>>>>>>
>>>>>> #include <asm-generic/qspinlock.h>
>>>>>> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
>>>>>> index b1b51f920b23..d4163679adc4 100644
>>>>>> --- a/arch/loongarch/kernel/paravirt.c
>>>>>> +++ b/arch/loongarch/kernel/paravirt.c
>>>>>> @@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
>>>>>> }
>>>>>>
>>>>>> #ifdef CONFIG_SMP
>>>>>> +DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
>>>>>> static int pv_time_cpu_online(unsigned int cpu)
>>>>>> {
>>>>>> unsigned long flags;
>>>>>> @@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
>>>>>>
>>>>>> return 0;
>>>>>> }
>>>>>> +
>>>>>> +bool notrace vcpu_is_preempted(int cpu)
>>>>>> +{
>>>>>> + struct kvm_steal_time *src;
>>>>>> +
>>>>>> + if (!static_branch_unlikely(&virt_preempt_key))
>>>>>> + return false;
>>>>>> +
>>>>>> + src = &per_cpu(steal_time, cpu);
>>>>>> + return !!(src->preempted & KVM_VCPU_PREEMPTED);
>>>>>> +}
>>>>>> +EXPORT_SYMBOL(vcpu_is_preempted);
>>>>>> #endif
>>>>>>
>>>>>> static void pv_cpu_reboot(void *unused)
>>>>>> @@ -308,6 +321,9 @@ int __init pv_time_init(void)
>>>>>> pr_err("Failed to install cpu hotplug callbacks\n");
>>>>>> return r;
>>>>>> }
>>>>>> +
>>>>>> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
>>>>>> + static_branch_enable(&virt_preempt_key);
>>>>>> #endif
>>>>>>
>>>>>> static_call_update(pv_steal_clock, paravt_steal_clock);
>>>>>> --
>>>>>> 2.39.3
>>>>>>
>>>>
>>>>
>>
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 8:32 ` Bibo Mao
@ 2025-11-24 9:03 ` Huacai Chen
2025-11-24 9:05 ` Bibo Mao
0 siblings, 1 reply; 16+ messages in thread
From: Huacai Chen @ 2025-11-24 9:03 UTC (permalink / raw)
To: Bibo Mao
Cc: Paolo Bonzini, WANG Xuerui, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list, kvm,
loongarch, linux-kernel, virtualization, x86
On Mon, Nov 24, 2025 at 4:35 PM Bibo Mao <maobibo@loongson.cn> wrote:
>
>
>
> On 2025/11/24 下午4:03, Huacai Chen wrote:
> > On Mon, Nov 24, 2025 at 3:50 PM Bibo Mao <maobibo@loongson.cn> wrote:
> >>
> >>
> >>
> >> On 2025/11/24 下午3:13, Huacai Chen wrote:
> >>> On Mon, Nov 24, 2025 at 3:03 PM Bibo Mao <maobibo@loongson.cn> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 2025/11/24 下午2:33, Huacai Chen wrote:
> >>>>> Hi, Bibo,
> >>>>>
> >>>>> On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
> >>>>>>
> >>>>>> Function vcpu_is_preempted() is used to check whether vCPU is preempted
> >>>>>> or not. Here add implementation with vcpu_is_preempted() when option
> >>>>>> CONFIG_PARAVIRT is enabled.
> >>>>>>
> >>>>>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> >>>>>> ---
> >>>>>> arch/loongarch/include/asm/qspinlock.h | 5 +++++
> >>>>>> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
> >>>>>> 2 files changed, 21 insertions(+)
> >>>>>>
> >>>>>> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
> >>>>>> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
> >>>>>> --- a/arch/loongarch/include/asm/qspinlock.h
> >>>>>> +++ b/arch/loongarch/include/asm/qspinlock.h
> >>>>>> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
> >>>>>> return true;
> >>>>>> }
> >>>>>>
> >>>>>> +#ifdef CONFIG_SMP
> >>>>>> +#define vcpu_is_preempted vcpu_is_preempted
> >>>>>> +bool vcpu_is_preempted(int cpu);
> >>>>> In V1 there is a build error because you reference mp_ops, so in V2
> >>>>> you needn't put it in CONFIG_SMP.
> >>>> The compile failure problem is that vcpu_is_preempted() is redefined in
> >>>> both arch/loongarch/kernel/paravirt.c and include/linux/sched.h
> >>> But other archs don't define vcpu_is_preempted() under CONFIG_SMP, and
> >> so what is advantage to implement this function if CONFIG_SMP is disabled?
> > 1. Keep consistency with other architectures.
> > 2. Keep it simple to reduce #ifdefs (and !SMP is just for build, not
> > very useful in practice).
> It seems that CONFIG_SMP can be removed in header file
> include/asm/qspinlock.h, since asm/spinlock.h and asm/qspinlock.h is
> only included when CONFIG_SMP is set, otherwise only linux/spinlock_up.h
> is included.
>
> >
> >>
> >>> you can consider to inline the whole vcpu_is_preempted() here.
> >> Defining the function vcpu_is_preempted() as inlined is not so easy for
> >> me, it beyond my ability now :(
> >>
> >> With static key method, the static key need be exported, all modules
> >> need apply the jump label, that is dangerous and I doubt whether it is
> >> deserved.
> > No, you have already done similar things in virt_spin_lock(), it is an
> > inline function and uses virt_spin_lock_key.
> virt_spin_lock is only called qspinlock in function
> queued_spin_lock_slowpath(). Function vcpu_is_preempted() is defined
> header file linux/sched.h, kernel module may use it.
Yes, if modules want to use it we need to EXPORT_SYMBOL. But don't
worry, static key infrastructure can handle this. Please see
cpu_feature_keys defined and used in
arch/powerpc/include/asm/cpu_has_feature.h, which is exported in
arch/powerpc/kernel/cputable.c.
Huacai
>
>
> >
> > Huacai
> >
> >>
> >> Regards
> >> Bibo Mao
> >>>
> >>>>
> >>>> The problem is that <asm/spinlock.h> is not included by sched.h, if
> >>>> CONFIG_SMP is disabled. Here is part of file include/linux/spinlock.h
> >>>> #ifdef CONFIG_SMP
> >>>> # include <asm/spinlock.h>
> >>>> #else
> >>>> # include <linux/spinlock_up.h>
> >>>> #endif
> >>>>
> >>>>> On the other hand, even if you really build a UP guest kernel, when
> >>>>> multiple guests run together, you probably need vcpu_is_preemtped.
> >>>> It is not relative with multiple VMs. When vcpu_is_preempted() is
> >>>> called, it is to detect whether dest CPU is preempted or not, the cpu
> >>>> from smp_processor_id() should not be preempted. So in generic
> >>>> vcpu_is_preempted() works on multiple vCPUs.
> >>> OK, I'm wrong here.
> >>>
> >>>
> >>> Huacai
> >>>
> >>>>
> >>>> Regards
> >>>> Bibo Mao
> >>>>>
> >>>>>
> >>>>> Huacai
> >>>>>
> >>>>>> +#endif
> >>>>>> +
> >>>>>> #endif /* CONFIG_PARAVIRT */
> >>>>>>
> >>>>>> #include <asm-generic/qspinlock.h>
> >>>>>> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
> >>>>>> index b1b51f920b23..d4163679adc4 100644
> >>>>>> --- a/arch/loongarch/kernel/paravirt.c
> >>>>>> +++ b/arch/loongarch/kernel/paravirt.c
> >>>>>> @@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
> >>>>>> }
> >>>>>>
> >>>>>> #ifdef CONFIG_SMP
> >>>>>> +DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
> >>>>>> static int pv_time_cpu_online(unsigned int cpu)
> >>>>>> {
> >>>>>> unsigned long flags;
> >>>>>> @@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
> >>>>>>
> >>>>>> return 0;
> >>>>>> }
> >>>>>> +
> >>>>>> +bool notrace vcpu_is_preempted(int cpu)
> >>>>>> +{
> >>>>>> + struct kvm_steal_time *src;
> >>>>>> +
> >>>>>> + if (!static_branch_unlikely(&virt_preempt_key))
> >>>>>> + return false;
> >>>>>> +
> >>>>>> + src = &per_cpu(steal_time, cpu);
> >>>>>> + return !!(src->preempted & KVM_VCPU_PREEMPTED);
> >>>>>> +}
> >>>>>> +EXPORT_SYMBOL(vcpu_is_preempted);
> >>>>>> #endif
> >>>>>>
> >>>>>> static void pv_cpu_reboot(void *unused)
> >>>>>> @@ -308,6 +321,9 @@ int __init pv_time_init(void)
> >>>>>> pr_err("Failed to install cpu hotplug callbacks\n");
> >>>>>> return r;
> >>>>>> }
> >>>>>> +
> >>>>>> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
> >>>>>> + static_branch_enable(&virt_preempt_key);
> >>>>>> #endif
> >>>>>>
> >>>>>> static_call_update(pv_steal_clock, paravt_steal_clock);
> >>>>>> --
> >>>>>> 2.39.3
> >>>>>>
> >>>>
> >>>>
> >>
> >>
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 9:03 ` Huacai Chen
@ 2025-11-24 9:05 ` Bibo Mao
2025-11-24 9:33 ` Huacai Chen
0 siblings, 1 reply; 16+ messages in thread
From: Bibo Mao @ 2025-11-24 9:05 UTC (permalink / raw)
To: Huacai Chen
Cc: Paolo Bonzini, WANG Xuerui, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list, kvm,
loongarch, linux-kernel, virtualization, x86
On 2025/11/24 下午5:03, Huacai Chen wrote:
> On Mon, Nov 24, 2025 at 4:35 PM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>>
>>
>> On 2025/11/24 下午4:03, Huacai Chen wrote:
>>> On Mon, Nov 24, 2025 at 3:50 PM Bibo Mao <maobibo@loongson.cn> wrote:
>>>>
>>>>
>>>>
>>>> On 2025/11/24 下午3:13, Huacai Chen wrote:
>>>>> On Mon, Nov 24, 2025 at 3:03 PM Bibo Mao <maobibo@loongson.cn> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 2025/11/24 下午2:33, Huacai Chen wrote:
>>>>>>> Hi, Bibo,
>>>>>>>
>>>>>>> On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
>>>>>>>>
>>>>>>>> Function vcpu_is_preempted() is used to check whether vCPU is preempted
>>>>>>>> or not. Here add implementation with vcpu_is_preempted() when option
>>>>>>>> CONFIG_PARAVIRT is enabled.
>>>>>>>>
>>>>>>>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>steal_time
>>>>>>>> ---
>>>>>>>> arch/loongarch/include/asm/qspinlock.h | 5 +++++
>>>>>>>> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
>>>>>>>> 2 files changed, 21 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
>>>>>>>> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
>>>>>>>> --- a/arch/loongarch/include/asm/qspinlock.h
>>>>>>>> +++ b/arch/loongarch/include/asm/qspinlock.h
>>>>>>>> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
>>>>>>>> return true;
>>>>>>>> }
>>>>>>>>
>>>>>>>> +#ifdef CONFIG_SMP
>>>>>>>> +#define vcpu_is_preempted vcpu_is_preempted
>>>>>>>> +bool vcpu_is_preempted(int cpu);
>>>>>>> In V1 there is a build error because you reference mp_ops, so in V2
>>>>>>> you needn't put it in CONFIG_SMP.
>>>>>> The compile failure problem is that vcpu_is_preempted() is redefined in
>>>>>> both arch/loongarch/kernel/paravirt.c and include/linux/sched.h
>>>>> But other archs don't define vcpu_is_preempted() under CONFIG_SMP, and
>>>> so what is advantage to implement this function if CONFIG_SMP is disabled?
>>> 1. Keep consistency with other architectures.
>>> 2. Keep it simple to reduce #ifdefs (and !SMP is just for build, not
>>> very useful in practice).
>> It seems that CONFIG_SMP can be removed in header file
>> include/asm/qspinlock.h, since asm/spinlock.h and asm/qspinlock.h is
>> only included when CONFIG_SMP is set, otherwise only linux/spinlock_up.h
>> is included.
>>
>>>
>>>>
>>>>> you can consider to inline the whole vcpu_is_preempted() here.
>>>> Defining the function vcpu_is_preempted() as inlined is not so easy for
>>>> me, it beyond my ability now :(
>>>>
>>>> With static key method, the static key need be exported, all modules
>>>> need apply the jump label, that is dangerous and I doubt whether it is
>>>> deserved.
>>> No, you have already done similar things in virt_spin_lock(), it is an
>>> inline function and uses virt_spin_lock_key.
>> virt_spin_lock is only called qspinlock in function
>> queued_spin_lock_slowpath(). Function vcpu_is_preempted() is defined
>> header file linux/sched.h, kernel module may use it.
> Yes, if modules want to use it we need to EXPORT_SYMBOL. But don't
> worry, static key infrastructure can handle this. Please see
> cpu_feature_keys defined and used in
> arch/powerpc/include/asm/cpu_has_feature.h, which is exported in
> arch/powerpc/kernel/cputable.c.
No, I do not want to do so. export static key and percpu steal_time
structure, just in order to implement one inline function.
>
> Huacai
>
>>
>>
>>>
>>> Huacai
>>>
>>>>
>>>> Regards
>>>> Bibo Mao
>>>>>
>>>>>>
>>>>>> The problem is that <asm/spinlock.h> is not included by sched.h, if
>>>>>> CONFIG_SMP is disabled. Here is part of file include/linux/spinlock.h
>>>>>> #ifdef CONFIG_SMP
>>>>>> # include <asm/spinlock.h>
>>>>>> #else
>>>>>> # include <linux/spinlock_up.h>
>>>>>> #endif
>>>>>>
>>>>>>> On the other hand, even if you really build a UP guest kernel, when
>>>>>>> multiple guests run together, you probably need vcpu_is_preemtped.
>>>>>> It is not relative with multiple VMs. When vcpu_is_preempted() is
>>>>>> called, it is to detect whether dest CPU is preempted or not, the cpu
>>>>>> from smp_processor_id() should not be preempted. So in generic
>>>>>> vcpu_is_preempted() works on multiple vCPUs.
>>>>> OK, I'm wrong here.
>>>>>
>>>>>
>>>>> Huacai
>>>>>
>>>>>>
>>>>>> Regards
>>>>>> Bibo Mao
>>>>>>>
>>>>>>>
>>>>>>> Huacai
>>>>>>>
>>>>>>>> +#endif
>>>>>>>> +
>>>>>>>> #endif /* CONFIG_PARAVIRT */
>>>>>>>>
>>>>>>>> #include <asm-generic/qspinlock.h>
>>>>>>>> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
>>>>>>>> index b1b51f920b23..d4163679adc4 100644
>>>>>>>> --- a/arch/loongarch/kernel/paravirt.c
>>>>>>>> +++ b/arch/loongarch/kernel/paravirt.c
>>>>>>>> @@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
>>>>>>>> }
>>>>>>>>
>>>>>>>> #ifdef CONFIG_SMP
>>>>>>>> +DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
>>>>>>>> static int pv_time_cpu_online(unsigned int cpu)
>>>>>>>> {
>>>>>>>> unsigned long flags;
>>>>>>>> @@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
>>>>>>>>
>>>>>>>> return 0;
>>>>>>>> }
>>>>>>>> +
>>>>>>>> +bool notrace vcpu_is_preempted(int cpu)
>>>>>>>> +{
>>>>>>>> + struct kvm_steal_time *src;
>>>>>>>> +
>>>>>>>> + if (!static_branch_unlikely(&virt_preempt_key))
>>>>>>>> + return false;
>>>>>>>> +
>>>>>>>> + src = &per_cpu(steal_time, cpu);
>>>>>>>> + return !!(src->preempted & KVM_VCPU_PREEMPTED);
>>>>>>>> +}
>>>>>>>> +EXPORT_SYMBOL(vcpu_is_preempted);
>>>>>>>> #endif
>>>>>>>>
>>>>>>>> static void pv_cpu_reboot(void *unused)
>>>>>>>> @@ -308,6 +321,9 @@ int __init pv_time_init(void)
>>>>>>>> pr_err("Failed to install cpu hotplug callbacks\n");
>>>>>>>> return r;
>>>>>>>> }
>>>>>>>> +
>>>>>>>> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
>>>>>>>> + static_branch_enable(&virt_preempt_key);
>>>>>>>> #endif
>>>>>>>>
>>>>>>>> static_call_update(pv_steal_clock, paravt_steal_clock);
>>>>>>>> --
>>>>>>>> 2.39.3
>>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-11-24 9:05 ` Bibo Mao
@ 2025-11-24 9:33 ` Huacai Chen
0 siblings, 0 replies; 16+ messages in thread
From: Huacai Chen @ 2025-11-24 9:33 UTC (permalink / raw)
To: Bibo Mao
Cc: Paolo Bonzini, WANG Xuerui, Juergen Gross, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list, kvm,
loongarch, linux-kernel, virtualization, x86
On Mon, Nov 24, 2025 at 5:08 PM Bibo Mao <maobibo@loongson.cn> wrote:
>
>
>
> On 2025/11/24 下午5:03, Huacai Chen wrote:
> > On Mon, Nov 24, 2025 at 4:35 PM Bibo Mao <maobibo@loongson.cn> wrote:
> >>
> >>
> >>
> >> On 2025/11/24 下午4:03, Huacai Chen wrote:
> >>> On Mon, Nov 24, 2025 at 3:50 PM Bibo Mao <maobibo@loongson.cn> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 2025/11/24 下午3:13, Huacai Chen wrote:
> >>>>> On Mon, Nov 24, 2025 at 3:03 PM Bibo Mao <maobibo@loongson.cn> wrote:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 2025/11/24 下午2:33, Huacai Chen wrote:
> >>>>>>> Hi, Bibo,
> >>>>>>>
> >>>>>>> On Mon, Nov 24, 2025 at 11:54 AM Bibo Mao <maobibo@loongson.cn> wrote:
> >>>>>>>>
> >>>>>>>> Function vcpu_is_preempted() is used to check whether vCPU is preempted
> >>>>>>>> or not. Here add implementation with vcpu_is_preempted() when option
> >>>>>>>> CONFIG_PARAVIRT is enabled.
> >>>>>>>>
> >>>>>>>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>steal_time
> >>>>>>>> ---
> >>>>>>>> arch/loongarch/include/asm/qspinlock.h | 5 +++++
> >>>>>>>> arch/loongarch/kernel/paravirt.c | 16 ++++++++++++++++
> >>>>>>>> 2 files changed, 21 insertions(+)
> >>>>>>>>
> >>>>>>>> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
> >>>>>>>> index e76d3aa1e1eb..9a5b7ba1f4cb 100644
> >>>>>>>> --- a/arch/loongarch/include/asm/qspinlock.h
> >>>>>>>> +++ b/arch/loongarch/include/asm/qspinlock.h
> >>>>>>>> @@ -34,6 +34,11 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
> >>>>>>>> return true;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> +#ifdef CONFIG_SMP
> >>>>>>>> +#define vcpu_is_preempted vcpu_is_preempted
> >>>>>>>> +bool vcpu_is_preempted(int cpu);
> >>>>>>> In V1 there is a build error because you reference mp_ops, so in V2
> >>>>>>> you needn't put it in CONFIG_SMP.
> >>>>>> The compile failure problem is that vcpu_is_preempted() is redefined in
> >>>>>> both arch/loongarch/kernel/paravirt.c and include/linux/sched.h
> >>>>> But other archs don't define vcpu_is_preempted() under CONFIG_SMP, and
> >>>> so what is advantage to implement this function if CONFIG_SMP is disabled?
> >>> 1. Keep consistency with other architectures.
> >>> 2. Keep it simple to reduce #ifdefs (and !SMP is just for build, not
> >>> very useful in practice).
> >> It seems that CONFIG_SMP can be removed in header file
> >> include/asm/qspinlock.h, since asm/spinlock.h and asm/qspinlock.h is
> >> only included when CONFIG_SMP is set, otherwise only linux/spinlock_up.h
> >> is included.
> >>
> >>>
> >>>>
> >>>>> you can consider to inline the whole vcpu_is_preempted() here.
> >>>> Defining the function vcpu_is_preempted() as inlined is not so easy for
> >>>> me, it beyond my ability now :(
> >>>>
> >>>> With static key method, the static key need be exported, all modules
> >>>> need apply the jump label, that is dangerous and I doubt whether it is
> >>>> deserved.
> >>> No, you have already done similar things in virt_spin_lock(), it is an
> >>> inline function and uses virt_spin_lock_key.
> >> virt_spin_lock is only called qspinlock in function
> >> queued_spin_lock_slowpath(). Function vcpu_is_preempted() is defined
> >> header file linux/sched.h, kernel module may use it.
> > Yes, if modules want to use it we need to EXPORT_SYMBOL. But don't
> > worry, static key infrastructure can handle this. Please see
> > cpu_feature_keys defined and used in
> > arch/powerpc/include/asm/cpu_has_feature.h, which is exported in
> > arch/powerpc/kernel/cputable.c.
> No, I do not want to do so. export static key and percpu steal_time> structure, just in order to implement one inline function.
In V1 you care about the performance of vcpu_is_preempted(), so inline
can satisfy your own requirement.
But this is your own choice, I don't insist on that. I only want to
remove CONFIG_SMP for vcpu_is_preempted().
Huacai
>
> >
> > Huacai
> >
> >>
> >>
> >>>
> >>> Huacai
> >>>
> >>>>
> >>>> Regards
> >>>> Bibo Mao
> >>>>>
> >>>>>>
> >>>>>> The problem is that <asm/spinlock.h> is not included by sched.h, if
> >>>>>> CONFIG_SMP is disabled. Here is part of file include/linux/spinlock.h
> >>>>>> #ifdef CONFIG_SMP
> >>>>>> # include <asm/spinlock.h>
> >>>>>> #else
> >>>>>> # include <linux/spinlock_up.h>
> >>>>>> #endif
> >>>>>>
> >>>>>>> On the other hand, even if you really build a UP guest kernel, when
> >>>>>>> multiple guests run together, you probably need vcpu_is_preemtped.
> >>>>>> It is not relative with multiple VMs. When vcpu_is_preempted() is
> >>>>>> called, it is to detect whether dest CPU is preempted or not, the cpu
> >>>>>> from smp_processor_id() should not be preempted. So in generic
> >>>>>> vcpu_is_preempted() works on multiple vCPUs.
> >>>>> OK, I'm wrong here.
> >>>>>
> >>>>>
> >>>>> Huacai
> >>>>>
> >>>>>>
> >>>>>> Regards
> >>>>>> Bibo Mao
> >>>>>>>
> >>>>>>>
> >>>>>>> Huacai
> >>>>>>>
> >>>>>>>> +#endif
> >>>>>>>> +
> >>>>>>>> #endif /* CONFIG_PARAVIRT */
> >>>>>>>>
> >>>>>>>> #include <asm-generic/qspinlock.h>
> >>>>>>>> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
> >>>>>>>> index b1b51f920b23..d4163679adc4 100644
> >>>>>>>> --- a/arch/loongarch/kernel/paravirt.c
> >>>>>>>> +++ b/arch/loongarch/kernel/paravirt.c
> >>>>>>>> @@ -246,6 +246,7 @@ static void pv_disable_steal_time(void)
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> #ifdef CONFIG_SMP
> >>>>>>>> +DEFINE_STATIC_KEY_FALSE(virt_preempt_key);
> >>>>>>>> static int pv_time_cpu_online(unsigned int cpu)
> >>>>>>>> {
> >>>>>>>> unsigned long flags;
> >>>>>>>> @@ -267,6 +268,18 @@ static int pv_time_cpu_down_prepare(unsigned int cpu)
> >>>>>>>>
> >>>>>>>> return 0;
> >>>>>>>> }
> >>>>>>>> +
> >>>>>>>> +bool notrace vcpu_is_preempted(int cpu)
> >>>>>>>> +{
> >>>>>>>> + struct kvm_steal_time *src;
> >>>>>>>> +
> >>>>>>>> + if (!static_branch_unlikely(&virt_preempt_key))
> >>>>>>>> + return false;
> >>>>>>>> +
> >>>>>>>> + src = &per_cpu(steal_time, cpu);
> >>>>>>>> + return !!(src->preempted & KVM_VCPU_PREEMPTED);
> >>>>>>>> +}
> >>>>>>>> +EXPORT_SYMBOL(vcpu_is_preempted);
> >>>>>>>> #endif
> >>>>>>>>
> >>>>>>>> static void pv_cpu_reboot(void *unused)
> >>>>>>>> @@ -308,6 +321,9 @@ int __init pv_time_init(void)
> >>>>>>>> pr_err("Failed to install cpu hotplug callbacks\n");
> >>>>>>>> return r;
> >>>>>>>> }
> >>>>>>>> +
> >>>>>>>> + if (kvm_para_has_feature(KVM_FEATURE_PREEMPT))
> >>>>>>>> + static_branch_enable(&virt_preempt_key);
> >>>>>>>> #endif
> >>>>>>>>
> >>>>>>>> static_call_update(pv_steal_clock, paravt_steal_clock);
> >>>>>>>> --
> >>>>>>>> 2.39.3
> >>>>>>>>
> >>>>>>
> >>>>>>
> >>>>
> >>>>
> >>
> >>
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2025-11-24 9:33 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-24 3:53 [PATCH v2 0/3] LoongArch: KVM: Add paravirt preempt support Bibo Mao
2025-11-24 3:53 ` [PATCH v2 1/3] LoongArch: KVM: Add paravirt preempt feature in hypervisor side Bibo Mao
2025-11-24 3:54 ` [PATCH v2 2/3] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side Bibo Mao
2025-11-24 6:33 ` Huacai Chen
2025-11-24 6:55 ` Jürgen Groß
2025-11-24 7:00 ` Bibo Mao
2025-11-24 7:13 ` Huacai Chen
2025-11-24 7:48 ` Bibo Mao
2025-11-24 8:03 ` Huacai Chen
2025-11-24 8:32 ` Bibo Mao
2025-11-24 9:03 ` Huacai Chen
2025-11-24 9:05 ` Bibo Mao
2025-11-24 9:33 ` Huacai Chen
2025-11-24 3:54 ` [PATCH v2 3/3] LoongArch: Add paravirt preempt print prompt Bibo Mao
2025-11-24 6:33 ` Huacai Chen
2025-11-24 7:10 ` Bibo Mao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®