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