linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] KVM: x86: Add PV IPIs support
@ 2018-06-29  9:51 Wanpeng Li
  2018-06-29  9:51 ` [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest Wanpeng Li
  2018-06-29  9:51 ` [PATCH 2/2] KVM: X86: Implement PV send IPI support Wanpeng Li
  0 siblings, 2 replies; 12+ messages in thread
From: Wanpeng Li @ 2018-06-29  9:51 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Radim Krčmář, Vitaly Kuznetsov

Using hypercall to send IPIs by one vmexit instead of one by one for
xAPIC/x2APIC physical mode and one vmexit per-cluster for x2APIC cluster 
mode. 

Even if enable qemu interrupt remapping and PV TLB Shootdown, I can still 
observe ~14% performance boost by ebizzy benchmark for 64 vCPUs VM, the 
total msr-induced vmexits reduce ~70%.

The patchset implements the PV IPIs for vCPUs <= 64 VM, this is really 
common in cloud environment, after this patchset is applied, I can continue 
to add > 64 vCPUs VM support and that implementation has to introduce more 
complex logic.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>

Wanpeng Li (2):
  KVM: X86: Implement PV IPI in linux guest
  KVM: X86: Implement PV send IPI support

 Documentation/virtual/kvm/cpuid.txt  |  4 +++
 arch/x86/include/uapi/asm/kvm_para.h |  1 +
 arch/x86/kernel/kvm.c                | 63 ++++++++++++++++++++++++++++++++++++
 arch/x86/kvm/cpuid.c                 |  3 +-
 arch/x86/kvm/x86.c                   | 25 ++++++++++++++
 include/uapi/linux/kvm_para.h        |  1 +
 6 files changed, 96 insertions(+), 1 deletion(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest
  2018-06-29  9:51 [PATCH 0/2] KVM: x86: Add PV IPIs support Wanpeng Li
@ 2018-06-29  9:51 ` Wanpeng Li
  2018-06-29 10:10   ` Vitaly Kuznetsov
                     ` (2 more replies)
  2018-06-29  9:51 ` [PATCH 2/2] KVM: X86: Implement PV send IPI support Wanpeng Li
  1 sibling, 3 replies; 12+ messages in thread
From: Wanpeng Li @ 2018-06-29  9:51 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Radim Krčmář, Vitaly Kuznetsov

From: Wanpeng Li <wanpengli@tencent.com>

Implement PV IPIs in guest kernel.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
---
 arch/x86/include/uapi/asm/kvm_para.h |  1 +
 arch/x86/kernel/kvm.c                | 63 ++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)

diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h
index 0ede697..19980ec 100644
--- a/arch/x86/include/uapi/asm/kvm_para.h
+++ b/arch/x86/include/uapi/asm/kvm_para.h
@@ -28,6 +28,7 @@
 #define KVM_FEATURE_PV_UNHALT		7
 #define KVM_FEATURE_PV_TLB_FLUSH	9
 #define KVM_FEATURE_ASYNC_PF_VMEXIT	10
+#define KVM_FEATURE_PV_SEND_IPI	11
 
 #define KVM_HINTS_REALTIME      0
 
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 5b2300b..b4f8dc3 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -454,6 +454,57 @@ static void __init sev_map_percpu_data(void)
 }
 
 #ifdef CONFIG_SMP
+
+static void __send_ipi_mask(const struct cpumask *mask, int vector)
+{
+	unsigned long flags, ipi_bitmap = 0;
+	int cpu;
+
+	local_irq_save(flags);
+
+	for_each_cpu(cpu, mask)
+		__set_bit(per_cpu(x86_cpu_to_apicid, cpu), &ipi_bitmap);
+	kvm_hypercall2(KVM_HC_SEND_IPI, ipi_bitmap, vector);
+
+	local_irq_restore(flags);
+}
+
+static void kvm_send_ipi_mask(const struct cpumask *mask, int vector)
+{
+	__send_ipi_mask(mask, vector);
+}
+
+static void kvm_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
+{
+	unsigned int this_cpu = smp_processor_id();
+	struct cpumask new_mask;
+	const struct cpumask *local_mask;
+
+	cpumask_copy(&new_mask, mask);
+	cpumask_clear_cpu(this_cpu, &new_mask);
+	local_mask = &new_mask;
+	__send_ipi_mask(local_mask, vector);
+}
+
+static void kvm_send_ipi_allbutself(int vector)
+{
+	kvm_send_ipi_mask_allbutself(cpu_online_mask, vector);
+}
+
+static void kvm_send_ipi_all(int vector)
+{
+	__send_ipi_mask(cpu_online_mask, vector);
+}
+
+static void kvm_setup_pv_ipi(void)
+{
+	apic->send_IPI_mask = kvm_send_ipi_mask;
+	apic->send_IPI_mask_allbutself = kvm_send_ipi_mask_allbutself;
+	apic->send_IPI_allbutself = kvm_send_ipi_allbutself;
+	apic->send_IPI_all = kvm_send_ipi_all;
+	printk("KVM setup pv IPIs\n");
+}
+
 static void __init kvm_smp_prepare_cpus(unsigned int max_cpus)
 {
 	native_smp_prepare_cpus(max_cpus);
@@ -624,12 +675,24 @@ static uint32_t __init kvm_detect(void)
 	return kvm_cpuid_base();
 }
 
+static void __init kvm_apic_init(void)
+{
+	if (kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI))
+		kvm_setup_pv_ipi();
+}
+
+static void __init kvm_init_platform(void)
+{
+	x86_platform.apic_post_init = kvm_apic_init;
+}
+
 const __initconst struct hypervisor_x86 x86_hyper_kvm = {
 	.name			= "KVM",
 	.detect			= kvm_detect,
 	.type			= X86_HYPER_KVM,
 	.init.guest_late_init	= kvm_guest_init,
 	.init.x2apic_available	= kvm_para_available,
+	.init.init_platform 	= kvm_init_platform,
 };
 
 static __init int activate_jump_labels(void)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/2] KVM: X86: Implement PV send IPI support
  2018-06-29  9:51 [PATCH 0/2] KVM: x86: Add PV IPIs support Wanpeng Li
  2018-06-29  9:51 ` [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest Wanpeng Li
@ 2018-06-29  9:51 ` Wanpeng Li
  2018-06-29 10:09   ` Vitaly Kuznetsov
  2018-06-29 10:45   ` Paolo Bonzini
  1 sibling, 2 replies; 12+ messages in thread
From: Wanpeng Li @ 2018-06-29  9:51 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Radim Krčmář, Vitaly Kuznetsov

From: Wanpeng Li <wanpengli@tencent.com>

Using hypercall to send IPIs by one vmexit instead of one by one for
xAPIC/x2APIC physical mode and one vmexit per-cluster for x2APIC cluster 
mode. 

Even if enable qemu interrupt remapping and PV TLB Shootdown, I can still 
observe ~14% performance boost by ebizzy benchmark for 64 vCPUs VM, the 
total msr-induced vmexits reduce ~70%.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
---
 Documentation/virtual/kvm/cpuid.txt |  4 ++++
 arch/x86/kvm/cpuid.c                |  3 ++-
 arch/x86/kvm/x86.c                  | 25 +++++++++++++++++++++++++
 include/uapi/linux/kvm_para.h       |  1 +
 4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/cpuid.txt b/Documentation/virtual/kvm/cpuid.txt
index ab022dc..d72359f 100644
--- a/Documentation/virtual/kvm/cpuid.txt
+++ b/Documentation/virtual/kvm/cpuid.txt
@@ -62,6 +62,10 @@ KVM_FEATURE_ASYNC_PF_VMEXIT        ||    10 || paravirtualized async PF VM exit
                                    ||       || can be enabled by setting bit 2
                                    ||       || when writing to msr 0x4b564d02
 ------------------------------------------------------------------------------
+KVM_FEATURE_PV_SEND_IPI            ||    11 || guest checks this feature bit
+                                   ||       || before enabling paravirtualized
+                                   ||       || send IPIs.
+------------------------------------------------------------------------------
 KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||    24 || host will warn if no guest-side
                                    ||       || per-cpu warps are expected in
                                    ||       || kvmclock.
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 7e042e3..7bcfa61 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -621,7 +621,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 			     (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) |
 			     (1 << KVM_FEATURE_PV_UNHALT) |
 			     (1 << KVM_FEATURE_PV_TLB_FLUSH) |
-			     (1 << KVM_FEATURE_ASYNC_PF_VMEXIT);
+			     (1 << KVM_FEATURE_ASYNC_PF_VMEXIT) |
+			     (1 << KVM_FEATURE_PV_SEND_IPI);
 
 		if (sched_info_on())
 			entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0046aa7..c2e6cdb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6689,6 +6689,27 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid)
 	kvm_irq_delivery_to_apic(kvm, NULL, &lapic_irq, NULL);
 }
 
+static void kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap, u8 vector)
+{
+	struct kvm_apic_map *map;
+	struct kvm_vcpu *vcpu;
+	struct kvm_lapic_irq lapic_irq = {0};
+	int i;
+
+	lapic_irq.delivery_mode = APIC_DM_FIXED;
+	lapic_irq.vector = vector;
+
+	rcu_read_lock();
+	map = rcu_dereference(kvm->arch.apic_map);
+
+	for_each_set_bit(i, &ipi_bitmap, sizeof(unsigned long)) {
+		vcpu = map->phys_map[i]->vcpu;
+		kvm_apic_set_irq(vcpu, &lapic_irq, NULL);
+	}
+
+	rcu_read_unlock();
+}
+
 void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu)
 {
 	vcpu->arch.apicv_active = false;
@@ -6738,6 +6759,10 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 		ret = kvm_pv_clock_pairing(vcpu, a0, a1);
 		break;
 #endif
+	case KVM_HC_SEND_IPI:
+		kvm_pv_send_ipi(vcpu->kvm, a0, a1);
+		ret = 0;
+		break;
 	default:
 		ret = -KVM_ENOSYS;
 		break;
diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h
index dcf629d..7395f38 100644
--- a/include/uapi/linux/kvm_para.h
+++ b/include/uapi/linux/kvm_para.h
@@ -26,6 +26,7 @@
 #define KVM_HC_MIPS_EXIT_VM		7
 #define KVM_HC_MIPS_CONSOLE_OUTPUT	8
 #define KVM_HC_CLOCK_PAIRING		9
+#define KVM_HC_SEND_IPI         	10
 
 /*
  * hypercalls use architecture specific
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: X86: Implement PV send IPI support
  2018-06-29  9:51 ` [PATCH 2/2] KVM: X86: Implement PV send IPI support Wanpeng Li
@ 2018-06-29 10:09   ` Vitaly Kuznetsov
  2018-06-29 10:48     ` Paolo Bonzini
  2018-06-29 10:45   ` Paolo Bonzini
  1 sibling, 1 reply; 12+ messages in thread
From: Vitaly Kuznetsov @ 2018-06-29 10:09 UTC (permalink / raw)
  To: Wanpeng Li; +Cc: linux-kernel, kvm, Paolo Bonzini, Radim Krčmář

Wanpeng Li <kernellwp@gmail.com> writes:

> From: Wanpeng Li <wanpengli@tencent.com>
>
> Using hypercall to send IPIs by one vmexit instead of one by one for
> xAPIC/x2APIC physical mode and one vmexit per-cluster for x2APIC cluster 
> mode. 
>
> Even if enable qemu interrupt remapping and PV TLB Shootdown, I can still 
> observe ~14% performance boost by ebizzy benchmark for 64 vCPUs VM, the 
> total msr-induced vmexits reduce ~70%.
>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Radim Krčmář <rkrcmar@redhat.com>
> Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
> Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
> ---
>  Documentation/virtual/kvm/cpuid.txt |  4 ++++
>  arch/x86/kvm/cpuid.c                |  3 ++-
>  arch/x86/kvm/x86.c                  | 25 +++++++++++++++++++++++++
>  include/uapi/linux/kvm_para.h       |  1 +
>  4 files changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/virtual/kvm/cpuid.txt b/Documentation/virtual/kvm/cpuid.txt
> index ab022dc..d72359f 100644
> --- a/Documentation/virtual/kvm/cpuid.txt
> +++ b/Documentation/virtual/kvm/cpuid.txt
> @@ -62,6 +62,10 @@ KVM_FEATURE_ASYNC_PF_VMEXIT        ||    10 || paravirtualized async PF VM exit
>                                     ||       || can be enabled by setting bit 2
>                                     ||       || when writing to msr 0x4b564d02
>  ------------------------------------------------------------------------------
> +KVM_FEATURE_PV_SEND_IPI            ||    11 || guest checks this feature bit
> +                                   ||       || before enabling paravirtualized
> +                                   ||       || send IPIs.

In case we decide to apply this as-is we'll likely need a new feature
for PV IPI with > 64 vCPUs (or how else would the guest know if the host
is capable or not?)

> +------------------------------------------------------------------------------
>  KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||    24 || host will warn if no guest-side
>                                     ||       || per-cpu warps are expected in
>                                     ||       || kvmclock.
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 7e042e3..7bcfa61 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -621,7 +621,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
>  			     (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) |
>  			     (1 << KVM_FEATURE_PV_UNHALT) |
>  			     (1 << KVM_FEATURE_PV_TLB_FLUSH) |
> -			     (1 << KVM_FEATURE_ASYNC_PF_VMEXIT);
> +			     (1 << KVM_FEATURE_ASYNC_PF_VMEXIT) |
> +			     (1 << KVM_FEATURE_PV_SEND_IPI);
>
>  		if (sched_info_on())
>  			entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 0046aa7..c2e6cdb 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6689,6 +6689,27 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid)
>  	kvm_irq_delivery_to_apic(kvm, NULL, &lapic_irq, NULL);
>  }
>
> +static void kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap, u8 vector)
> +{
> +	struct kvm_apic_map *map;
> +	struct kvm_vcpu *vcpu;
> +	struct kvm_lapic_irq lapic_irq = {0};
> +	int i;
> +
> +	lapic_irq.delivery_mode = APIC_DM_FIXED;
> +	lapic_irq.vector = vector;
> +
> +	rcu_read_lock();
> +	map = rcu_dereference(kvm->arch.apic_map);
> +
> +	for_each_set_bit(i, &ipi_bitmap, sizeof(unsigned long)) {
> +		vcpu = map->phys_map[i]->vcpu;
> +		kvm_apic_set_irq(vcpu, &lapic_irq, NULL);
> +	}
> +
> +	rcu_read_unlock();
> +}
> +
>  void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu)
>  {
>  	vcpu->arch.apicv_active = false;
> @@ -6738,6 +6759,10 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
>  		ret = kvm_pv_clock_pairing(vcpu, a0, a1);
>  		break;
>  #endif
> +	case KVM_HC_SEND_IPI:
> +		kvm_pv_send_ipi(vcpu->kvm, a0, a1);
> +		ret = 0;
> +		break;
>  	default:
>  		ret = -KVM_ENOSYS;
>  		break;
> diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h
> index dcf629d..7395f38 100644
> --- a/include/uapi/linux/kvm_para.h
> +++ b/include/uapi/linux/kvm_para.h
> @@ -26,6 +26,7 @@
>  #define KVM_HC_MIPS_EXIT_VM		7
>  #define KVM_HC_MIPS_CONSOLE_OUTPUT	8
>  #define KVM_HC_CLOCK_PAIRING		9
> +#define KVM_HC_SEND_IPI         	10
>
>  /*
>   * hypercalls use architecture specific

-- 
  Vitaly

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest
  2018-06-29  9:51 ` [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest Wanpeng Li
@ 2018-06-29 10:10   ` Vitaly Kuznetsov
  2018-06-30 10:04     ` Wanpeng Li
  2018-06-29 11:22   ` kbuild test robot
  2018-06-29 13:01   ` kbuild test robot
  2 siblings, 1 reply; 12+ messages in thread
From: Vitaly Kuznetsov @ 2018-06-29 10:10 UTC (permalink / raw)
  To: Wanpeng Li; +Cc: linux-kernel, kvm, Paolo Bonzini, Radim Krčmář

Wanpeng Li <kernellwp@gmail.com> writes:

> From: Wanpeng Li <wanpengli@tencent.com>
>
> Implement PV IPIs in guest kernel.
>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Radim Krčmář <rkrcmar@redhat.com>
> Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
> Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
> ---
>  arch/x86/include/uapi/asm/kvm_para.h |  1 +
>  arch/x86/kernel/kvm.c                | 63 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 64 insertions(+)
>
> diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h
> index 0ede697..19980ec 100644
> --- a/arch/x86/include/uapi/asm/kvm_para.h
> +++ b/arch/x86/include/uapi/asm/kvm_para.h
> @@ -28,6 +28,7 @@
>  #define KVM_FEATURE_PV_UNHALT		7
>  #define KVM_FEATURE_PV_TLB_FLUSH	9
>  #define KVM_FEATURE_ASYNC_PF_VMEXIT	10
> +#define KVM_FEATURE_PV_SEND_IPI	11
>
>  #define KVM_HINTS_REALTIME      0
>
> diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
> index 5b2300b..b4f8dc3 100644
> --- a/arch/x86/kernel/kvm.c
> +++ b/arch/x86/kernel/kvm.c
> @@ -454,6 +454,57 @@ static void __init sev_map_percpu_data(void)
>  }
>
>  #ifdef CONFIG_SMP
> +
> +static void __send_ipi_mask(const struct cpumask *mask, int vector)
> +{
> +	unsigned long flags, ipi_bitmap = 0;
> +	int cpu;
> +
> +	local_irq_save(flags);
> +
> +	for_each_cpu(cpu, mask)
> +		__set_bit(per_cpu(x86_cpu_to_apicid, cpu), &ipi_bitmap);

We need a protection against per_cpu(x86_cpu_to_apicid, cpu) > here.

> +	kvm_hypercall2(KVM_HC_SEND_IPI, ipi_bitmap, vector);
> +
> +	local_irq_restore(flags);
> +}
> +
> +static void kvm_send_ipi_mask(const struct cpumask *mask, int vector)
> +{
> +	__send_ipi_mask(mask, vector);
> +}
> +
> +static void kvm_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
> +{
> +	unsigned int this_cpu = smp_processor_id();
> +	struct cpumask new_mask;
> +	const struct cpumask *local_mask;
> +
> +	cpumask_copy(&new_mask, mask);
> +	cpumask_clear_cpu(this_cpu, &new_mask);
> +	local_mask = &new_mask;
> +	__send_ipi_mask(local_mask, vector);
> +}
> +
> +static void kvm_send_ipi_allbutself(int vector)
> +{
> +	kvm_send_ipi_mask_allbutself(cpu_online_mask, vector);
> +}
> +
> +static void kvm_send_ipi_all(int vector)
> +{
> +	__send_ipi_mask(cpu_online_mask, vector);
> +}
> +
> +static void kvm_setup_pv_ipi(void)
> +{
> +	apic->send_IPI_mask = kvm_send_ipi_mask;
> +	apic->send_IPI_mask_allbutself = kvm_send_ipi_mask_allbutself;
> +	apic->send_IPI_allbutself = kvm_send_ipi_allbutself;
> +	apic->send_IPI_all = kvm_send_ipi_all;
> +	printk("KVM setup pv IPIs\n");
> +}
> +
>  static void __init kvm_smp_prepare_cpus(unsigned int max_cpus)
>  {
>  	native_smp_prepare_cpus(max_cpus);
> @@ -624,12 +675,24 @@ static uint32_t __init kvm_detect(void)
>  	return kvm_cpuid_base();
>  }
>
> +static void __init kvm_apic_init(void)
> +{
> +	if (kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI))
> +		kvm_setup_pv_ipi();
> +}
> +
> +static void __init kvm_init_platform(void)
> +{
> +	x86_platform.apic_post_init = kvm_apic_init;
> +}
> +
>  const __initconst struct hypervisor_x86 x86_hyper_kvm = {
>  	.name			= "KVM",
>  	.detect			= kvm_detect,
>  	.type			= X86_HYPER_KVM,
>  	.init.guest_late_init	= kvm_guest_init,
>  	.init.x2apic_available	= kvm_para_available,
> +	.init.init_platform 	= kvm_init_platform,
>  };
>
>  static __init int activate_jump_labels(void)

-- 
  Vitaly

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: X86: Implement PV send IPI support
  2018-06-29  9:51 ` [PATCH 2/2] KVM: X86: Implement PV send IPI support Wanpeng Li
  2018-06-29 10:09   ` Vitaly Kuznetsov
@ 2018-06-29 10:45   ` Paolo Bonzini
  2018-06-30 10:04     ` Wanpeng Li
  1 sibling, 1 reply; 12+ messages in thread
From: Paolo Bonzini @ 2018-06-29 10:45 UTC (permalink / raw)
  To: Wanpeng Li, linux-kernel, kvm
  Cc: Radim Krčmář, Vitaly Kuznetsov

On 29/06/2018 11:51, Wanpeng Li wrote:
> From: Wanpeng Li <wanpengli@tencent.com>
> 
> Using hypercall to send IPIs by one vmexit instead of one by one for
> xAPIC/x2APIC physical mode and one vmexit per-cluster for x2APIC cluster 
> mode. 
> 
> Even if enable qemu interrupt remapping and PV TLB Shootdown, I can still 
> observe ~14% performance boost by ebizzy benchmark for 64 vCPUs VM, the 
> total msr-induced vmexits reduce ~70%.
> 
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Radim Krčmář <rkrcmar@redhat.com>
> Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
> Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
> ---
>  Documentation/virtual/kvm/cpuid.txt |  4 ++++
>  arch/x86/kvm/cpuid.c                |  3 ++-
>  arch/x86/kvm/x86.c                  | 25 +++++++++++++++++++++++++
>  include/uapi/linux/kvm_para.h       |  1 +
>  4 files changed, 32 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/virtual/kvm/cpuid.txt b/Documentation/virtual/kvm/cpuid.txt
> index ab022dc..d72359f 100644
> --- a/Documentation/virtual/kvm/cpuid.txt
> +++ b/Documentation/virtual/kvm/cpuid.txt
> @@ -62,6 +62,10 @@ KVM_FEATURE_ASYNC_PF_VMEXIT        ||    10 || paravirtualized async PF VM exit
>                                     ||       || can be enabled by setting bit 2
>                                     ||       || when writing to msr 0x4b564d02
>  ------------------------------------------------------------------------------
> +KVM_FEATURE_PV_SEND_IPI            ||    11 || guest checks this feature bit
> +                                   ||       || before enabling paravirtualized
> +                                   ||       || send IPIs.

It's not "enabling" but "using".  You also need to document the
hypercall itself.

Paolo

> +------------------------------------------------------------------------------
>  KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||    24 || host will warn if no guest-side
>                                     ||       || per-cpu warps are expected in
>                                     ||       || kvmclock.
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 7e042e3..7bcfa61 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -621,7 +621,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
>  			     (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) |
>  			     (1 << KVM_FEATURE_PV_UNHALT) |
>  			     (1 << KVM_FEATURE_PV_TLB_FLUSH) |
> -			     (1 << KVM_FEATURE_ASYNC_PF_VMEXIT);
> +			     (1 << KVM_FEATURE_ASYNC_PF_VMEXIT) |
> +			     (1 << KVM_FEATURE_PV_SEND_IPI);
>  
>  		if (sched_info_on())
>  			entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 0046aa7..c2e6cdb 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6689,6 +6689,27 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid)
>  	kvm_irq_delivery_to_apic(kvm, NULL, &lapic_irq, NULL);
>  }
>  
> +static void kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap, u8 vector)
> +{
> +	struct kvm_apic_map *map;
> +	struct kvm_vcpu *vcpu;
> +	struct kvm_lapic_irq lapic_irq = {0};
> +	int i;
> +
> +	lapic_irq.delivery_mode = APIC_DM_FIXED;
> +	lapic_irq.vector = vector;
> +
> +	rcu_read_lock();
> +	map = rcu_dereference(kvm->arch.apic_map);
> +
> +	for_each_set_bit(i, &ipi_bitmap, sizeof(unsigned long)) {
> +		vcpu = map->phys_map[i]->vcpu;
> +		kvm_apic_set_irq(vcpu, &lapic_irq, NULL);
> +	}
> +
> +	rcu_read_unlock();
> +}
> +
>  void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu)
>  {
>  	vcpu->arch.apicv_active = false;
> @@ -6738,6 +6759,10 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
>  		ret = kvm_pv_clock_pairing(vcpu, a0, a1);
>  		break;
>  #endif
> +	case KVM_HC_SEND_IPI:
> +		kvm_pv_send_ipi(vcpu->kvm, a0, a1);
> +		ret = 0;
> +		break;
>  	default:
>  		ret = -KVM_ENOSYS;
>  		break;
> diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h
> index dcf629d..7395f38 100644
> --- a/include/uapi/linux/kvm_para.h
> +++ b/include/uapi/linux/kvm_para.h
> @@ -26,6 +26,7 @@
>  #define KVM_HC_MIPS_EXIT_VM		7
>  #define KVM_HC_MIPS_CONSOLE_OUTPUT	8
>  #define KVM_HC_CLOCK_PAIRING		9
> +#define KVM_HC_SEND_IPI         	10
>  
>  /*
>   * hypercalls use architecture specific
> 


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: X86: Implement PV send IPI support
  2018-06-29 10:09   ` Vitaly Kuznetsov
@ 2018-06-29 10:48     ` Paolo Bonzini
  2018-06-30 10:05       ` Wanpeng Li
  0 siblings, 1 reply; 12+ messages in thread
From: Paolo Bonzini @ 2018-06-29 10:48 UTC (permalink / raw)
  To: Vitaly Kuznetsov, Wanpeng Li
  Cc: linux-kernel, kvm, Radim Krčmář

On 29/06/2018 12:09, Vitaly Kuznetsov wrote:
>> +KVM_FEATURE_PV_SEND_IPI            ||    11 || guest checks this feature bit
>> +                                   ||       || before enabling paravirtualized
>> +                                   ||       || send IPIs.
> In case we decide to apply this as-is we'll likely need a new feature
> for PV IPI with > 64 vCPUs (or how else would the guest know if the host
> is capable or not?)
> 

Yes, it makes sense.  Perhaps we can do one of the following, or both:

1) add an argument for a "base vCPU id", so that you can use the
hypercall to send the IPI to CPUs 64..127, 128..191 etc.

2) have two bitmask arguments so that one hypercall handles 128 vCPUs.

to remove or limit the need for the more generic hypercall.

Paolo

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest
  2018-06-29  9:51 ` [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest Wanpeng Li
  2018-06-29 10:10   ` Vitaly Kuznetsov
@ 2018-06-29 11:22   ` kbuild test robot
  2018-06-29 13:01   ` kbuild test robot
  2 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2018-06-29 11:22 UTC (permalink / raw)
  To: Wanpeng Li
  Cc: kbuild-all, linux-kernel, kvm, Paolo Bonzini,
	Radim Krčmář,
	Vitaly Kuznetsov

[-- Attachment #1: Type: text/plain, Size: 1360 bytes --]

Hi Wanpeng,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvm/linux-next]
[also build test ERROR on v4.18-rc2 next-20180629]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Wanpeng-Li/KVM-x86-Add-PV-IPIs-support/20180629-185314
base:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next
config: x86_64-randconfig-x003-201825 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   arch/x86/kernel/kvm.c: In function 'kvm_apic_init':
>> arch/x86/kernel/kvm.c:681:3: error: implicit declaration of function 'kvm_setup_pv_ipi'; did you mean 'idt_setup_traps'? [-Werror=implicit-function-declaration]
      kvm_setup_pv_ipi();
      ^~~~~~~~~~~~~~~~
      idt_setup_traps
   cc1: some warnings being treated as errors

vim +681 arch/x86/kernel/kvm.c

   677	
   678	static void __init kvm_apic_init(void)
   679	{
   680		if (kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI))
 > 681			kvm_setup_pv_ipi();
   682	}
   683	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32495 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest
  2018-06-29  9:51 ` [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest Wanpeng Li
  2018-06-29 10:10   ` Vitaly Kuznetsov
  2018-06-29 11:22   ` kbuild test robot
@ 2018-06-29 13:01   ` kbuild test robot
  2 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2018-06-29 13:01 UTC (permalink / raw)
  To: Wanpeng Li
  Cc: kbuild-all, linux-kernel, kvm, Paolo Bonzini,
	Radim Krčmář,
	Vitaly Kuznetsov

[-- Attachment #1: Type: text/plain, Size: 1307 bytes --]

Hi Wanpeng,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvm/linux-next]
[also build test ERROR on v4.18-rc2 next-20180629]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Wanpeng-Li/KVM-x86-Add-PV-IPIs-support/20180629-185314
base:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next
config: i386-randconfig-a0-201825 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   arch/x86//kernel/kvm.c: In function 'kvm_apic_init':
>> arch/x86//kernel/kvm.c:681:3: error: implicit declaration of function 'kvm_setup_pv_ipi' [-Werror=implicit-function-declaration]
      kvm_setup_pv_ipi();
      ^
   cc1: some warnings being treated as errors

vim +/kvm_setup_pv_ipi +681 arch/x86//kernel/kvm.c

   677	
   678	static void __init kvm_apic_init(void)
   679	{
   680		if (kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI))
 > 681			kvm_setup_pv_ipi();
   682	}
   683	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27664 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest
  2018-06-29 10:10   ` Vitaly Kuznetsov
@ 2018-06-30 10:04     ` Wanpeng Li
  0 siblings, 0 replies; 12+ messages in thread
From: Wanpeng Li @ 2018-06-30 10:04 UTC (permalink / raw)
  To: Vitaly Kuznetsov; +Cc: LKML, kvm, Paolo Bonzini, Radim Krcmar

On Fri, 29 Jun 2018 at 18:10, Vitaly Kuznetsov <vkuznets@redhat.com> wrote:
>
> Wanpeng Li <kernellwp@gmail.com> writes:
>
> > From: Wanpeng Li <wanpengli@tencent.com>
> >
> > Implement PV IPIs in guest kernel.
> >
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > Cc: Radim Krčmář <rkrcmar@redhat.com>
> > Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
> > Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
> > ---
> >  arch/x86/include/uapi/asm/kvm_para.h |  1 +
> >  arch/x86/kernel/kvm.c                | 63 ++++++++++++++++++++++++++++++++++++
> >  2 files changed, 64 insertions(+)
> >
> > diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h
> > index 0ede697..19980ec 100644
> > --- a/arch/x86/include/uapi/asm/kvm_para.h
> > +++ b/arch/x86/include/uapi/asm/kvm_para.h
> > @@ -28,6 +28,7 @@
> >  #define KVM_FEATURE_PV_UNHALT                7
> >  #define KVM_FEATURE_PV_TLB_FLUSH     9
> >  #define KVM_FEATURE_ASYNC_PF_VMEXIT  10
> > +#define KVM_FEATURE_PV_SEND_IPI      11
> >
> >  #define KVM_HINTS_REALTIME      0
> >
> > diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
> > index 5b2300b..b4f8dc3 100644
> > --- a/arch/x86/kernel/kvm.c
> > +++ b/arch/x86/kernel/kvm.c
> > @@ -454,6 +454,57 @@ static void __init sev_map_percpu_data(void)
> >  }
> >
> >  #ifdef CONFIG_SMP
> > +
> > +static void __send_ipi_mask(const struct cpumask *mask, int vector)
> > +{
> > +     unsigned long flags, ipi_bitmap = 0;
> > +     int cpu;
> > +
> > +     local_irq_save(flags);
> > +
> > +     for_each_cpu(cpu, mask)
> > +             __set_bit(per_cpu(x86_cpu_to_apicid, cpu), &ipi_bitmap);
>
> We need a protection against per_cpu(x86_cpu_to_apicid, cpu) > here.

Will do in v2.

Regards,
Wanpeng Li

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: X86: Implement PV send IPI support
  2018-06-29 10:45   ` Paolo Bonzini
@ 2018-06-30 10:04     ` Wanpeng Li
  0 siblings, 0 replies; 12+ messages in thread
From: Wanpeng Li @ 2018-06-30 10:04 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: LKML, kvm, Radim Krcmar, Vitaly Kuznetsov

On Fri, 29 Jun 2018 at 18:45, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 29/06/2018 11:51, Wanpeng Li wrote:
> > From: Wanpeng Li <wanpengli@tencent.com>
> >
> > Using hypercall to send IPIs by one vmexit instead of one by one for
> > xAPIC/x2APIC physical mode and one vmexit per-cluster for x2APIC cluster
> > mode.
> >
> > Even if enable qemu interrupt remapping and PV TLB Shootdown, I can still
> > observe ~14% performance boost by ebizzy benchmark for 64 vCPUs VM, the
> > total msr-induced vmexits reduce ~70%.
> >
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > Cc: Radim Krčmář <rkrcmar@redhat.com>
> > Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
> > Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
> > ---
> >  Documentation/virtual/kvm/cpuid.txt |  4 ++++
> >  arch/x86/kvm/cpuid.c                |  3 ++-
> >  arch/x86/kvm/x86.c                  | 25 +++++++++++++++++++++++++
> >  include/uapi/linux/kvm_para.h       |  1 +
> >  4 files changed, 32 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/virtual/kvm/cpuid.txt b/Documentation/virtual/kvm/cpuid.txt
> > index ab022dc..d72359f 100644
> > --- a/Documentation/virtual/kvm/cpuid.txt
> > +++ b/Documentation/virtual/kvm/cpuid.txt
> > @@ -62,6 +62,10 @@ KVM_FEATURE_ASYNC_PF_VMEXIT        ||    10 || paravirtualized async PF VM exit
> >                                     ||       || can be enabled by setting bit 2
> >                                     ||       || when writing to msr 0x4b564d02
> >  ------------------------------------------------------------------------------
> > +KVM_FEATURE_PV_SEND_IPI            ||    11 || guest checks this feature bit
> > +                                   ||       || before enabling paravirtualized
> > +                                   ||       || send IPIs.
>
> It's not "enabling" but "using".  You also need to document the
> hypercall itself.

Will fix it in v2.

Regards,
Wanpeng Li

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: X86: Implement PV send IPI support
  2018-06-29 10:48     ` Paolo Bonzini
@ 2018-06-30 10:05       ` Wanpeng Li
  0 siblings, 0 replies; 12+ messages in thread
From: Wanpeng Li @ 2018-06-30 10:05 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Vitaly Kuznetsov, LKML, kvm, Radim Krcmar

On Fri, 29 Jun 2018 at 18:49, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 29/06/2018 12:09, Vitaly Kuznetsov wrote:
> >> +KVM_FEATURE_PV_SEND_IPI            ||    11 || guest checks this feature bit
> >> +                                   ||       || before enabling paravirtualized
> >> +                                   ||       || send IPIs.
> > In case we decide to apply this as-is we'll likely need a new feature
> > for PV IPI with > 64 vCPUs (or how else would the guest know if the host
> > is capable or not?)
> >
>
> Yes, it makes sense.  Perhaps we can do one of the following, or both:
>
> 1) add an argument for a "base vCPU id", so that you can use the
> hypercall to send the IPI to CPUs 64..127, 128..191 etc.
>
> 2) have two bitmask arguments so that one hypercall handles 128 vCPUs.
>
> to remove or limit the need for the more generic hypercall.

Have already done 2) in v2, will send out later.

Regards,
Wanpeng Li

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2018-06-30 10:05 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-29  9:51 [PATCH 0/2] KVM: x86: Add PV IPIs support Wanpeng Li
2018-06-29  9:51 ` [PATCH 1/2] KVM: X86: Implement PV IPI in linux guest Wanpeng Li
2018-06-29 10:10   ` Vitaly Kuznetsov
2018-06-30 10:04     ` Wanpeng Li
2018-06-29 11:22   ` kbuild test robot
2018-06-29 13:01   ` kbuild test robot
2018-06-29  9:51 ` [PATCH 2/2] KVM: X86: Implement PV send IPI support Wanpeng Li
2018-06-29 10:09   ` Vitaly Kuznetsov
2018-06-29 10:48     ` Paolo Bonzini
2018-06-30 10:05       ` Wanpeng Li
2018-06-29 10:45   ` Paolo Bonzini
2018-06-30 10:04     ` Wanpeng Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).