On Thu, Apr 22, 2021, Kenta Ishiguro wrote: > This commit monitors IPI communication between vCPUs and leverages the > relationship between vCPUs to select boost candidates. > > Cc: David Hildenbrand <david@xxxxxxxxxx> > Signed-off-by: Kenta Ishiguro <kentaishiguro@xxxxxxxxxxxxxxxxxxxx> > --- > arch/x86/kvm/lapic.c | 14 ++++++++++++++ > arch/x86/kvm/vmx/vmx.c | 2 ++ > include/linux/kvm_host.h | 5 +++++ > virt/kvm/kvm_main.c | 26 ++++++++++++++++++++++++-- > 4 files changed, 45 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c > index cc369b9ad8f1..c8d967ddecf9 100644 > --- a/arch/x86/kvm/lapic.c > +++ b/arch/x86/kvm/lapic.c > @@ -1269,6 +1269,18 @@ void kvm_apic_set_eoi_accelerated(struct kvm_vcpu *vcpu, int vector) > } > EXPORT_SYMBOL_GPL(kvm_apic_set_eoi_accelerated); > > +static void mark_ipi_receiver(struct kvm_lapic *apic, struct kvm_lapic_irq *irq) > +{ > + struct kvm_vcpu *dest_vcpu; > + u64 prev_ipi_received; > + > + dest_vcpu = kvm_get_vcpu_by_id(apic->vcpu->kvm, irq->dest_id); > + if (READ_ONCE(dest_vcpu->sched_outed)) { > + prev_ipi_received = READ_ONCE(dest_vcpu->ipi_received); > + WRITE_ONCE(dest_vcpu->ipi_received, prev_ipi_received | (1 << apic->vcpu->vcpu_id)); The lack of "ull" on '1' actually means this will probably go sideways at >32 vCPUs. Regardless, there needs to be an actual fallback path when the number of vCPUs exceeds what the IPI-boost can support. That said, it should be quite easy to allocate a bitmap to support an arbitrary number of vCPUs. > + } > +} > + > void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 icr_low, u32 icr_high) > { > struct kvm_lapic_irq irq; > @@ -1287,6 +1299,8 @@ void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 icr_low, u32 icr_high) > > trace_kvm_apic_ipi(icr_low, irq.dest_id); > > + mark_ipi_receiver(apic, &irq); > + > kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq, NULL); > } > > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c > index 29b40e092d13..ced50935a38b 100644 > --- a/arch/x86/kvm/vmx/vmx.c > +++ b/arch/x86/kvm/vmx/vmx.c > @@ -6718,6 +6718,8 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu) > vmcs_write32(PLE_WINDOW, vmx->ple_window); > } > > + WRITE_ONCE(vcpu->ipi_received, 0); > + > /* > * We did this in prepare_switch_to_guest, because it needs to > * be within srcu_read_lock. > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > index 1b65e7204344..6726aeec03e7 100644 > --- a/include/linux/kvm_host.h > +++ b/include/linux/kvm_host.h > @@ -320,6 +320,11 @@ struct kvm_vcpu { > #endif > bool preempted; > bool ready; > + bool sched_outed; > + /* > + * The current implementation of strict boost supports up to 64 vCPUs > + */ > + u64 ipi_received; ... > struct kvm_vcpu_arch arch; > struct kvm_dirty_ring dirty_ring; > };