From c21ed3de727066b42b58c96ade84ec77ac590890 Mon Sep 17 00:00:00 2001 From: Jack Bendtsen Date: Thu, 4 Sep 2025 17:31:29 +1000 Subject: [PATCH] vmm: optimize vioapic_write() Running Windows 11 / Server 2025 inside bhyve causes this function to be called extremely frequently. As a result, vm_smp_rendezvous() is called very often, which causes all but 1 core that the VM has access to to synchronize. As a result, in our testing, these cores would spend roughly 70% of their time inside vm_handle_rendezvous(), causing Windows to slow to a crawl. This is the same code path as mentioned in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=268794 We ran a simple test program that finds the number of prime numbers below a certain threshold, a simple O(n^2) single-thread performance benchmark. On Windows Server 2022: > number of primes less than 100000: 9592 > wall time: 1.69249 secs > user time: 1.6875 secs Windows Server 2025 *without* this patch: > number of primes less than 100000: 9592 > wall time: 3.21974 secs > user time: 2.89063 secs Windows Server 2025 *WITH* this patch: > number of primes less than 100000: 9592 > wall time: 1.72742 secs > user time: 1.65625 secs Given that the purpose of the routine passed into vm_smp_rendezvous() is to "Reset the vlapic's trigger-mode register to reflect the ioapic pin configuration", this change seems reasonable. Signed-off-by: Jack Bendtsen --- sys/amd64/vmm/io/vioapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/amd64/vmm/io/vioapic.c b/sys/amd64/vmm/io/vioapic.c index 7df6193d6dc0ce..c88bf25fe3e6c6 100644 --- a/sys/amd64/vmm/io/vioapic.c +++ b/sys/amd64/vmm/io/vioapic.c @@ -374,7 +374,7 @@ vioapic_write(struct vioapic *vioapic, struct vcpu *vcpu, uint32_t addr, * to update their vlapic trigger-mode registers. */ changed = last ^ vioapic->rtbl[pin].reg; - if (changed & ~(IOART_INTMASK | IOART_INTPOL)) { + if (changed & IOART_TRGRMOD) { VIOAPIC_CTR1(vioapic, "ioapic pin%d: recalculate " "vlapic trigger-mode register", pin); VIOAPIC_UNLOCK(vioapic);