Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: LAPIC: Micro optimize IPI latency

This patch optimizes the virtual IPI emulation sequence:

write ICR2 write ICR2
write ICR read ICR2
read ICR ==> send virtual IPI
read ICR2 write ICR
send virtual IPI

It can reduce kvm-unit-tests/vmexit.flat IPI testing latency(from sender
send IPI to sender receive the ACK) from 3319 cycles to 3203 cycles on
SKylake server.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Wanpeng Li and committed by
Paolo Bonzini
2b0911d1 1cfff4d9

+4 -5
+4 -5
arch/x86/kvm/lapic.c
··· 1198 1198 } 1199 1199 EXPORT_SYMBOL_GPL(kvm_apic_set_eoi_accelerated); 1200 1200 1201 - static void apic_send_ipi(struct kvm_lapic *apic) 1201 + static void apic_send_ipi(struct kvm_lapic *apic, u32 icr_low, u32 icr_high) 1202 1202 { 1203 - u32 icr_low = kvm_lapic_get_reg(apic, APIC_ICR); 1204 - u32 icr_high = kvm_lapic_get_reg(apic, APIC_ICR2); 1205 1203 struct kvm_lapic_irq irq; 1206 1204 1207 1205 irq.vector = icr_low & APIC_VECTOR_MASK; ··· 1912 1914 } 1913 1915 case APIC_ICR: 1914 1916 /* No delay here, so we always clear the pending bit */ 1915 - kvm_lapic_set_reg(apic, APIC_ICR, val & ~(1 << 12)); 1916 - apic_send_ipi(apic); 1917 + val &= ~(1 << 12); 1918 + apic_send_ipi(apic, val, kvm_lapic_get_reg(apic, APIC_ICR2)); 1919 + kvm_lapic_set_reg(apic, APIC_ICR, val); 1917 1920 break; 1918 1921 1919 1922 case APIC_ICR2: