* [PATCH v3 0/2] LoongArch: KVM: Add paravirt preempt support
@ 2025-12-02 2:48 Bibo Mao
2025-12-02 2:48 ` [PATCH v3 1/2] LoongArch: KVM: Add paravirt preempt feature in hypervisor side Bibo Mao
2025-12-02 2:48 ` [PATCH v3 2/2] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side Bibo Mao
0 siblings, 2 replies; 6+ messages in thread
From: Bibo Mao @ 2025-12-02 2:48 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%
---
v2 ... v3:
1. Remove CONFIG_SMP checking in header file asm/qspinlock.h, since
this file is included only if CONFIG_SMP is defined.
2. Replace internal variable pv_preempted with static_key_enabled()
method.
3. Add static type define with variable virt_preempt_key.
4. Merge previous patch 2 and patch 3 into one patch.
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 (2):
LoongArch: KVM: Add paravirt preempt feature in hypervisor side
LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
arch/loongarch/include/asm/kvm_host.h | 2 +
arch/loongarch/include/asm/kvm_para.h | 4 +-
arch/loongarch/include/asm/qspinlock.h | 3 ++
arch/loongarch/include/uapi/asm/kvm.h | 1 +
arch/loongarch/include/uapi/asm/kvm_para.h | 1 +
arch/loongarch/kernel/paravirt.c | 23 +++++++++-
arch/loongarch/kvm/vcpu.c | 53 +++++++++++++++++++++-
arch/loongarch/kvm/vm.c | 5 +-
8 files changed, 88 insertions(+), 4 deletions(-)
base-commit: 4664fb427c8fd0080f40109f5e2b2090a6fb0c84
--
2.39.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/2] LoongArch: KVM: Add paravirt preempt feature in hypervisor side
2025-12-02 2:48 [PATCH v3 0/2] LoongArch: KVM: Add paravirt preempt support Bibo Mao
@ 2025-12-02 2:48 ` Bibo Mao
2025-12-02 2:48 ` [PATCH v3 2/2] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side Bibo Mao
1 sibling, 0 replies; 6+ messages in thread
From: Bibo Mao @ 2025-12-02 2:48 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] 6+ messages in thread
* [PATCH v3 2/2] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-12-02 2:48 [PATCH v3 0/2] LoongArch: KVM: Add paravirt preempt support Bibo Mao
2025-12-02 2:48 ` [PATCH v3 1/2] LoongArch: KVM: Add paravirt preempt feature in hypervisor side Bibo Mao
@ 2025-12-02 2:48 ` Bibo Mao
2025-12-03 15:56 ` Jürgen Groß
2025-12-06 13:04 ` Huacai Chen
1 sibling, 2 replies; 6+ messages in thread
From: Bibo Mao @ 2025-12-02 2:48 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 | 3 +++
arch/loongarch/kernel/paravirt.c | 23 ++++++++++++++++++++++-
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
index e76d3aa1e1eb..fa3eaf7e48f2 100644
--- a/arch/loongarch/include/asm/qspinlock.h
+++ b/arch/loongarch/include/asm/qspinlock.h
@@ -34,6 +34,9 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
return true;
}
+#define vcpu_is_preempted vcpu_is_preempted
+bool vcpu_is_preempted(int cpu);
+
#endif /* CONFIG_PARAVIRT */
#include <asm-generic/qspinlock.h>
diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
index b1b51f920b23..b61a93c6aec8 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
+static 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);
@@ -318,7 +334,12 @@ int __init pv_time_init(void)
static_key_slow_inc(¶virt_steal_rq_enabled);
#endif
- pr_info("Using paravirt steal-time\n");
+#ifdef CONFIG_SMP
+ if (static_key_enabled(&virt_preempt_key))
+ pr_info("Using paravirt steal-time with preempt enabled\n");
+ else
+#endif
+ pr_info("Using paravirt steal-time with preempt disabled\n");
return 0;
}
--
2.39.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-12-02 2:48 ` [PATCH v3 2/2] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side Bibo Mao
@ 2025-12-03 15:56 ` Jürgen Groß
2025-12-06 13:04 ` Huacai Chen
1 sibling, 0 replies; 6+ messages in thread
From: Jürgen Groß @ 2025-12-03 15:56 UTC (permalink / raw)
To: Bibo Mao, Paolo Bonzini, Huacai Chen, WANG Xuerui, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list
Cc: kvm, loongarch, linux-kernel, virtualization, x86
[-- Attachment #1.1.1: Type: text/plain, Size: 325 bytes --]
On 02.12.25 03:48, Bibo Mao 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>
Acked-by: Juergen Gross <jgross@suse.com>
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] 6+ messages in thread
* Re: [PATCH v3 2/2] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-12-02 2:48 ` [PATCH v3 2/2] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side Bibo Mao
2025-12-03 15:56 ` Jürgen Groß
@ 2025-12-06 13:04 ` Huacai Chen
2025-12-18 12:10 ` Bibo Mao
1 sibling, 1 reply; 6+ messages in thread
From: Huacai Chen @ 2025-12-06 13:04 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 Tue, Dec 2, 2025 at 10:48 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 | 3 +++
> arch/loongarch/kernel/paravirt.c | 23 ++++++++++++++++++++++-
> 2 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
> index e76d3aa1e1eb..fa3eaf7e48f2 100644
> --- a/arch/loongarch/include/asm/qspinlock.h
> +++ b/arch/loongarch/include/asm/qspinlock.h
> @@ -34,6 +34,9 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
> return true;
> }
>
> +#define vcpu_is_preempted vcpu_is_preempted
> +bool vcpu_is_preempted(int cpu);
> +
> #endif /* CONFIG_PARAVIRT */
>
> #include <asm-generic/qspinlock.h>
> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
> index b1b51f920b23..b61a93c6aec8 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
> +static 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);
> @@ -318,7 +334,12 @@ int __init pv_time_init(void)
> static_key_slow_inc(¶virt_steal_rq_enabled);
> #endif
>
> - pr_info("Using paravirt steal-time\n");
> +#ifdef CONFIG_SMP
Linux kernel is removing non-SMP step by step [1].
https://kernelnewbies.org/Linux_6.17#Unconditionally_compile_task_scheduler_with_SMP_support
Though we cannot remove all "#ifdef CONFIG_SMP" at present, we can at
least stop adding more.
So I prefer to make this whole patch out of CONFIG_SMP. But if you
don't like this, you can at least move the virt_preempt_key
declaration out of "#ifdef CONFIG_SMP", then the #ifdefs here can be
removed.
Huacai
> + if (static_key_enabled(&virt_preempt_key))
> + pr_info("Using paravirt steal-time with preempt enabled\n");
> + else
> +#endif
> + pr_info("Using paravirt steal-time with preempt disabled\n");
>
> return 0;
> }
> --
> 2.39.3
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side
2025-12-06 13:04 ` Huacai Chen
@ 2025-12-18 12:10 ` Bibo Mao
0 siblings, 0 replies; 6+ messages in thread
From: Bibo Mao @ 2025-12-18 12:10 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/12/6 下午9:04, Huacai Chen wrote:
> Hi, Bibo,
>
> On Tue, Dec 2, 2025 at 10:48 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 | 3 +++
>> arch/loongarch/kernel/paravirt.c | 23 ++++++++++++++++++++++-
>> 2 files changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
>> index e76d3aa1e1eb..fa3eaf7e48f2 100644
>> --- a/arch/loongarch/include/asm/qspinlock.h
>> +++ b/arch/loongarch/include/asm/qspinlock.h
>> @@ -34,6 +34,9 @@ static inline bool virt_spin_lock(struct qspinlock *lock)
>> return true;
>> }
>>
>> +#define vcpu_is_preempted vcpu_is_preempted
>> +bool vcpu_is_preempted(int cpu);
>> +
>> #endif /* CONFIG_PARAVIRT */
>>
>> #include <asm-generic/qspinlock.h>
>> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
>> index b1b51f920b23..b61a93c6aec8 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
>> +static 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);
>> @@ -318,7 +334,12 @@ int __init pv_time_init(void)
>> static_key_slow_inc(¶virt_steal_rq_enabled);
>> #endif
>>
>> - pr_info("Using paravirt steal-time\n");
>> +#ifdef CONFIG_SMP
>
> Linux kernel is removing non-SMP step by step [1].
> https://kernelnewbies.org/Linux_6.17#Unconditionally_compile_task_scheduler_with_SMP_support
>
> Though we cannot remove all "#ifdef CONFIG_SMP" at present, we can at
> least stop adding more.
>
> So I prefer to make this whole patch out of CONFIG_SMP. But if you
> don't like this, you can at least move the virt_preempt_key
> declaration out of "#ifdef CONFIG_SMP", then the #ifdefs here can be
> removed.
Sorry, I just notice this mail.
Will move virt_preempt_key out of CONFIG_SMP in next version.
Regards
Bibo Mao
>
> Huacai
>
>> + if (static_key_enabled(&virt_preempt_key))
>> + pr_info("Using paravirt steal-time with preempt enabled\n");
>> + else
>> +#endif
>> + pr_info("Using paravirt steal-time with preempt disabled\n");
>>
>> return 0;
>> }
>> --
>> 2.39.3
>>
>>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-12-18 12:12 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-02 2:48 [PATCH v3 0/2] LoongArch: KVM: Add paravirt preempt support Bibo Mao
2025-12-02 2:48 ` [PATCH v3 1/2] LoongArch: KVM: Add paravirt preempt feature in hypervisor side Bibo Mao
2025-12-02 2:48 ` [PATCH v3 2/2] LoongArch: Add paravirt support with vcpu_is_preempted() in guest side Bibo Mao
2025-12-03 15:56 ` Jürgen Groß
2025-12-06 13:04 ` Huacai Chen
2025-12-18 12: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®