mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [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(&paravirt_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(&paravirt_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(&paravirt_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®