* [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
* 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 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 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
* [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 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 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
* 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: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
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).