arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/msrs.c | 7 +- arch/x86/kvm/svm/nested.c | 112 +++- arch/x86/kvm/svm/svm.h | 16 + arch/x86/kvm/vmx/nested.c | 356 ++++++++++-- arch/x86/kvm/vmx/vmx.c | 11 +- arch/x86/kvm/vmx/vmx.h | 16 +- arch/x86/kvm/x86.c | 181 ++++--- arch/x86/kvm/x86.h | 33 ++ arch/x86/kvm/xen.c | 279 +++++----- include/linux/kvm_host.h | 86 ++- include/linux/kvm_types.h | 52 +- include/linux/srcu.h | 7 + tools/testing/selftests/kvm/Makefile.kvm | 2 + .../selftests/kvm/x86/nested_transition_bench.c | 204 +++++++ .../selftests/kvm/x86/vmx_apic_update_test.c | 299 +++++++++++ virt/kvm/kvm_main.c | 9 + virt/kvm/pfncache.c | 596 +++++++++++++++++---- 18 files changed, 1876 insertions(+), 392 deletions(-)
Now that Paul et al have so kindly provided atomic SRCU for us, it would
be churlish not to use it.
Based on the merge of kvm/next (d4b7fb647204) with Paul's dev.2026.09.17a¹
as posted last week², this series:
• Converts the GPC to use atomic SRCU, ditching the rwlock which was a
scaling and latency problem, and which PREEMPT_RT hated because it
turned the rwlock into a sleeping lock.
• Cleans up the intentional lack of dirty-tracking of Xen shinfo and
vcpu_info pages (Sean).
• Converts steal-time / preempted status to use gfn_to_pfn_cache. (Carsten)
• Reinstates guest-mode pinning: replacing the old GUEST_USES_PFN mode,
letting nested state pages be cached and pinned while in guest context.
• nVMX: Uses GPC for the L1 MSR bitmap, and guest mode for APIC access
and vAPIC pages. (Fred)
• nSVM: Uses GPC for vmcb12 / MSR-permissions / IO-permissions pages. This
cuts the vmcb12 transition cost measurably (selftest included).
• Returns -EAGAIN from cache lookups which race with memslot updates,
and re-posts KVM_REQ_GET_NESTED_STATE_PAGES on memslot generation
bumps so pinned caches are revalidated lazily.
Tested: rcutorture atomic-SRCU (srcud, reader_flavor=0x10) on three
hosts; KVM selftests including new invalidation and transition tests;
>1 week soak of VM lifecycle + invalidation reproducers on 128-way
RT+KASAN+lockdep, 192-way RT and 192-way PREEMPT_DYNAMIC hosts. And
booted an actual Xen guest in QEMU a few times...
¹ https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev.2026.09.17a
² https://lore.kernel.org/rcu/20260919003521.3134552-1-paulmck@kernel.org/
There have been previous series which attempt to deal with various parts
of GPC locking, and the steal time one has definitely been posted before
a few times, but let's just call this v1:
https://git.infradead.org/?p=users/dwmw2/linux.git;a=shortlog;h=refs/heads/gpc-srcu
Carsten Stollmaier (1):
KVM: x86: Use gfn_to_pfn_cache for steal time / preempted status
David Woodhouse (10):
KVM: pfncache: Use atomic SRCU for readers instead of a rwlock
KVM: x86: Request the guest TLB flush from record_steal_time()
KVM: pfncache: Add guest-mode pinning (GUEST_USES_PFN successor)
KVM: pfncache: Return -EAGAIN for a lookup which hits an invalid memslot
KVM: x86: Post KVM_REQ_GET_NESTED_STATE_PAGES on memslot updates
KVM: x86: Move nested GPC lock helpers to x86.h as kvm_gpc_lock_page()
KVM: nSVM: Use a gfn_to_pfn_cache for the vmcb12 page
KVM: nSVM: Cache L1's MSR permissions map pages
KVM: nSVM: Cache L1's IO permissions map pages
KVM: selftests: Add nested transition benchmark
Fred Griffoul (3):
KVM: nVMX: Implement cache for L1 MSR bitmap
KVM: nVMX: Use pinned pfncache for L1 APIC virtualization pages
KVM: selftests: Add nested VMX APIC cache invalidation test
Sean Christopherson (3):
KVM: x86/xen: Extract delivery of event to vCPU into a separate helper
KVM: x86/xen: Explicitly tag "shared info" page as never being dirty tracked
KVM: x86/xen: Don't dirty track "vCPU info" page
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/msrs.c | 7 +-
arch/x86/kvm/svm/nested.c | 112 +++-
arch/x86/kvm/svm/svm.h | 16 +
arch/x86/kvm/vmx/nested.c | 356 ++++++++++--
arch/x86/kvm/vmx/vmx.c | 11 +-
arch/x86/kvm/vmx/vmx.h | 16 +-
arch/x86/kvm/x86.c | 181 ++++---
arch/x86/kvm/x86.h | 33 ++
arch/x86/kvm/xen.c | 279 +++++-----
include/linux/kvm_host.h | 86 ++-
include/linux/kvm_types.h | 52 +-
include/linux/srcu.h | 7 +
tools/testing/selftests/kvm/Makefile.kvm | 2 +
.../selftests/kvm/x86/nested_transition_bench.c | 204 +++++++
.../selftests/kvm/x86/vmx_apic_update_test.c | 299 +++++++++++
virt/kvm/kvm_main.c | 9 +
virt/kvm/pfncache.c | 596 +++++++++++++++++----
18 files changed, 1876 insertions(+), 392 deletions(-)
On Sun, 2026-09-20 at 21:49 +0100, David Woodhouse wrote: > > There have been previous series which attempt to deal with various parts > of GPC locking, and the steal time one has definitely been posted before > a few times, but let's just call this v1: > https://git.infradead.org/?p=users/dwmw2/linux.git;a=shortlog;h=refs/heads/gpc-srcu I think I'd actually posted more of the previous RCU work than I remembered, so perhaps this ought to have been a v4 of https://lore.kernel.org/all/20260805195528.3853473-1-dwmw@amazon.co.uk/ but the entertaining parts of it probably stand alone now with the atomic SRCU. On the Sashiko feedback, much of it is down to lack of visibility of atomic SRCU, and some parts are now fixed in my tree for what I shall call v2 unless someone really objects to the above omission. The interesting one is the EVTCHNOP_send deadlock, spinning on -EAGAIN while in a kvm->srcu read section which prevents the memslot update from ever completing. I've made it raise a REQ which completes it from outside the read section, and added a selftest. The MSR bitmap cache in patch 10 did lose the read-only mapping support; I've added a readonly option to the GPC. The iteration count in patch 17's commit message did indeed say 100k where the code only does 10k. Fixed the former.
Hi David, Thanks for the series. I noticed the testing results, but didn't see a performance comparison for the SRCU change itself. Do you happen to have any numbers comparing the GPC invalidation latency with regular SRCU vs. `synchronize_srcu_atomic()`? If there are also numbers with the reader-free fastpath, that would be useful for understanding its impact as well. No need to run anything specifically if you don't already have the numbers. Thanks, Kunwu On Mon, Sep 21, 2026 at 5:19 AM David Woodhouse <dwmw2@infradead.org> wrote: > > Now that Paul et al have so kindly provided atomic SRCU for us, it would > be churlish not to use it. > > Based on the merge of kvm/next (d4b7fb647204) with Paul's dev.2026.09.17a¹ > as posted last week², this series: > > • Converts the GPC to use atomic SRCU, ditching the rwlock which was a > scaling and latency problem, and which PREEMPT_RT hated because it > turned the rwlock into a sleeping lock. > > • Cleans up the intentional lack of dirty-tracking of Xen shinfo and > vcpu_info pages (Sean). > > • Converts steal-time / preempted status to use gfn_to_pfn_cache. (Carsten) > > • Reinstates guest-mode pinning: replacing the old GUEST_USES_PFN mode, > letting nested state pages be cached and pinned while in guest context. > > • nVMX: Uses GPC for the L1 MSR bitmap, and guest mode for APIC access > and vAPIC pages. (Fred) > > • nSVM: Uses GPC for vmcb12 / MSR-permissions / IO-permissions pages. This > cuts the vmcb12 transition cost measurably (selftest included). > > • Returns -EAGAIN from cache lookups which race with memslot updates, > and re-posts KVM_REQ_GET_NESTED_STATE_PAGES on memslot generation > bumps so pinned caches are revalidated lazily. > > Tested: rcutorture atomic-SRCU (srcud, reader_flavor=0x10) on three > hosts; KVM selftests including new invalidation and transition tests; > >1 week soak of VM lifecycle + invalidation reproducers on 128-way > RT+KASAN+lockdep, 192-way RT and 192-way PREEMPT_DYNAMIC hosts. And > booted an actual Xen guest in QEMU a few times... > > ¹ https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev.2026.09.17a > ² https://lore.kernel.org/rcu/20260919003521.3134552-1-paulmck@kernel.org/ > > There have been previous series which attempt to deal with various parts > of GPC locking, and the steal time one has definitely been posted before > a few times, but let's just call this v1: > https://git.infradead.org/?p=users/dwmw2/linux.git;a=shortlog;h=refs/heads/gpc-srcu > > Carsten Stollmaier (1): > KVM: x86: Use gfn_to_pfn_cache for steal time / preempted status > > David Woodhouse (10): > KVM: pfncache: Use atomic SRCU for readers instead of a rwlock > KVM: x86: Request the guest TLB flush from record_steal_time() > KVM: pfncache: Add guest-mode pinning (GUEST_USES_PFN successor) > KVM: pfncache: Return -EAGAIN for a lookup which hits an invalid memslot > KVM: x86: Post KVM_REQ_GET_NESTED_STATE_PAGES on memslot updates > KVM: x86: Move nested GPC lock helpers to x86.h as kvm_gpc_lock_page() > KVM: nSVM: Use a gfn_to_pfn_cache for the vmcb12 page > KVM: nSVM: Cache L1's MSR permissions map pages > KVM: nSVM: Cache L1's IO permissions map pages > KVM: selftests: Add nested transition benchmark > > Fred Griffoul (3): > KVM: nVMX: Implement cache for L1 MSR bitmap > KVM: nVMX: Use pinned pfncache for L1 APIC virtualization pages > KVM: selftests: Add nested VMX APIC cache invalidation test > > Sean Christopherson (3): > KVM: x86/xen: Extract delivery of event to vCPU into a separate helper > KVM: x86/xen: Explicitly tag "shared info" page as never being dirty tracked > KVM: x86/xen: Don't dirty track "vCPU info" page > > > arch/x86/include/asm/kvm_host.h | 2 +- > arch/x86/kvm/msrs.c | 7 +- > arch/x86/kvm/svm/nested.c | 112 +++- > arch/x86/kvm/svm/svm.h | 16 + > arch/x86/kvm/vmx/nested.c | 356 ++++++++++-- > arch/x86/kvm/vmx/vmx.c | 11 +- > arch/x86/kvm/vmx/vmx.h | 16 +- > arch/x86/kvm/x86.c | 181 ++++--- > arch/x86/kvm/x86.h | 33 ++ > arch/x86/kvm/xen.c | 279 +++++----- > include/linux/kvm_host.h | 86 ++- > include/linux/kvm_types.h | 52 +- > include/linux/srcu.h | 7 + > tools/testing/selftests/kvm/Makefile.kvm | 2 + > .../selftests/kvm/x86/nested_transition_bench.c | 204 +++++++ > .../selftests/kvm/x86/vmx_apic_update_test.c | 299 +++++++++++ > virt/kvm/kvm_main.c | 9 + > virt/kvm/pfncache.c | 596 +++++++++++++++++---- > 18 files changed, 1876 insertions(+), 392 deletions(-)
On Tue, 2026-09-22 at 11:16 +0800, KunWu Chan wrote: > Do you happen to have any numbers comparing the GPC invalidation > latency with regular SRCU vs. `synchronize_srcu_atomic()`? If there > are also numbers with the reader-free fastpath, that would be useful > for understanding its impact as well. Yeah, I built some latency tests and was posting results in the earlier thread¹, on a few different test hosts. I compared against the existing rwlock, as well as SRCU both with and without the try_synchronize_srcu() fast path. Mostly looking at the invalidation latency, since that was Sean's stated concern with the original RCU-based proof of concept. All from the same test: 12 concurrent guest-memory invalidation reproducers hammering the Xen shinfo/vcpu_info caches, 300 second windows, measuring the invalidation drain end-to-end. 192-way Granite Rapids, PREEMPT_RT production config: rwlock (before this series) avg 4.4µs max 3.85ms synchronize_srcu_expedited() drain avg 8.6µs max 810µs synchronize_srcu_atomic() + fastpath avg ~3µs max 801µs The A/B numbers I have for the reader-free fast path were on different hardware (128-way Ice Lake, production-like config): synchronize_srcu_atomic(), no fastpath avg 8.0µs max 6.0ms with the inline no-readers proof avg 3.6µs max 326µs If you want, it isn't much effort for me to tell my friend to redo any of the measurements. ¹ https://lore.kernel.org/all/0d4af6318ac67486858be1df8d436147b444a2d2.camel@infradead.org/
On Tue, 22 Sep 2026 12:37:43 +0200 David Woodhouse <dwmw2@infradead.org> wrote: > On Tue, 2026-09-22 at 11:16 +0800, KunWu Chan wrote: > > Do you happen to have any numbers comparing the GPC invalidation > > latency with regular SRCU vs. `synchronize_srcu_atomic()`? If there > > are also numbers with the reader-free fastpath, that would be useful > > for understanding its impact as well. > > Yeah, I built some latency tests and was posting results in the earlier > thread¹, on a few different test hosts. > > I compared against the existing rwlock, as well as SRCU both with and > without the try_synchronize_srcu() fast path. Mostly looking at the > invalidation latency, since that was Sean's stated concern with the > original RCU-based proof of concept. > > All from the same test: 12 concurrent guest-memory invalidation > reproducers hammering the Xen shinfo/vcpu_info caches, 300 second > windows, measuring the invalidation drain end-to-end. > > 192-way Granite Rapids, PREEMPT_RT production config: > > rwlock (before this series) avg 4.4µs max 3.85ms > synchronize_srcu_expedited() drain avg 8.6µs max 810µs > synchronize_srcu_atomic() + fastpath avg ~3µs max 801µs > > The A/B numbers I have for the reader-free fast path were on different > hardware (128-way Ice Lake, production-like config): > > synchronize_srcu_atomic(), no fastpath avg 8.0µs max 6.0ms > with the inline no-readers proof avg 3.6µs max 326µs > > If you want, it isn't much effort for me to tell my friend to redo any > of the measurements. > > ¹ https://lore.kernel.org/all/0d4af6318ac67486858be1df8d436147b444a2d2.camel@infradead.org/ > Hi David, Thanks, this is very helpful. I've put the results together below. KVM GPC invalidation drain latency 128-way Ice Lake: ┌──────────────────────────────────┬──────────────┬──────────────┐ │ Implementation │ Avg │ Max │ ├──────────────────────────────────┼──────────────┼──────────────┤ │ Baseline (rwlock) │ not provided │ not provided │ ├──────────────────────────────────┼──────────────┼──────────────┤ │ synchronize_srcu_expedited() │ not provided │ not provided │ ├──────────────────────────────────┼──────────────┼──────────────┤ │ synchronize_srcu_atomic() │ 8.0us │ 6.0ms │ ├──────────────────────────────────┼──────────────┼──────────────┤ │ synchronize_srcu_atomic() + │ 3.6us │ 326us │ │ reader-free fastpath │ │ │ └──────────────────────────────────┴──────────────┴──────────────┘ 192-way Granite Rapids: ┌──────────────────────────────────┬──────────────┬──────────────┐ │ Implementation │ Avg │ Max │ ├──────────────────────────────────┼──────────────┼──────────────┤ │ Baseline (rwlock) │ 4.4us │ 3.85ms │ ├──────────────────────────────────┼──────────────┼──────────────┤ │ synchronize_srcu_expedited() │ 8.6us │ 810us │ ├──────────────────────────────────┼──────────────┼──────────────┤ │ synchronize_srcu_atomic() │ not provided │ not provided │ ├──────────────────────────────────┼──────────────┼──────────────┤ │ synchronize_srcu_atomic() + │ ~3us │ 801us │ │ reader-free fastpath │ │ │ └──────────────────────────────────┴──────────────┴──────────────┘ Note: Avg / Max are the average and maximum end-to-end invalidation drain latency. The measurements use 12 concurrent guest-memory invalidation reproducers hammering the Xen shinfo/vcpu_info caches over 300-second windows. On the 128-way Ice Lake system, the reader-free fastpath reduces the average latency from 8.0us to 3.6us, and the maximum from 6.0ms to 326us. The 192-way Granite Rapids result is from a separate hardware configuration, so I kept it separate from the 128-way A/B comparison. The only missing comparison is the 192-way Granite Rapids result for synchronize_srcu_atomic() without the reader-free fastpath. If you already have that result, it would be useful to add it. No need to rerun the measurement just for this table if you don't have it. Could you please confirm that I transcribed the numbers correctly? Thanks, Kunwu
On Wed, 2026-09-23 at 17:54 +0800, Kunwu Chan wrote: > Thanks, this is very helpful. I've put the results together below. That looks correct. I had my friend dig out the missing parts from runs I haven't posted, and do the runs it hadn't run. 128-way Ice Lake, PREEMPT_DYNAMIC production-like config: rwlock avg 0.59µs max 330µs synchronize_srcu_expedited() drain avg 3.65µs max 4383µs synchronize_srcu_atomic(), no fastpath avg 8.04µs max 6034µs synchronize_srcu_atomic() + fastpath avg 3.59µs max 326µs 192-way Granite Rapids, PREEMPT_RT production config: rwlock avg 4.4µs max 3854µs synchronize_srcu_expedited() drain avg 8.6µs max 810µs synchronize_srcu_atomic(), no fastpath avg 12.0µs max 620µs synchronize_srcu_atomic() + fastpath avg ~3µs max 801µs The max values here are noisy and can vary by 2x per (300s) run. The averages are fairly clean, and I think I have per-bucket breakdowns for all of them if you really want to dig into it. Astute readers will note that rwlock actually wins on average on the "production-like" config, that the max is in the same ballpark as the srcu_atomic+fastpath too, and wonder why we bothered... the point is not just that rwlocks are the wrong thing to use for PREEMPT_RT, but also that all we're benchmarking in the above tables is the *invalidation* not the read side, which scales a *lot* better in the SRCU model and doesn't bounce cache lines around.
On Wed, Sep 23, 2026 at 8:05 PM David Woodhouse <dwmw2@infradead.org> wrote: > > On Wed, 2026-09-23 at 17:54 +0800, Kunwu Chan wrote: > > Thanks, this is very helpful. I've put the results together below. > > That looks correct. I had my friend dig out the missing parts from runs > I haven't posted, and do the runs it hadn't run. > > 128-way Ice Lake, PREEMPT_DYNAMIC production-like config: > > rwlock avg 0.59µs max 330µs > synchronize_srcu_expedited() drain avg 3.65µs max 4383µs > synchronize_srcu_atomic(), no fastpath avg 8.04µs max 6034µs > synchronize_srcu_atomic() + fastpath avg 3.59µs max 326µs > > 192-way Granite Rapids, PREEMPT_RT production config: > > rwlock avg 4.4µs max 3854µs > synchronize_srcu_expedited() drain avg 8.6µs max 810µs > synchronize_srcu_atomic(), no fastpath avg 12.0µs max 620µs > synchronize_srcu_atomic() + fastpath avg ~3µs max 801µs > > The max values here are noisy and can vary by 2x per (300s) run. The > averages are fairly clean, and I think I have per-bucket breakdowns for > all of them if you really want to dig into it. > > Astute readers will note that rwlock actually wins on average on the > "production-like" config, that the max is in the same ballpark as the > srcu_atomic+fastpath too, and wonder why we bothered... the point is > not just that rwlocks are the wrong thing to use for PREEMPT_RT, but > also that all we're benchmarking in the above tables is the > *invalidation* not the read side, which scales a *lot* better in the > SRCU model and doesn't bounce cache lines around. Hi David, Thanks again to you and your friend for digging out the missing results and running the additional measurements. I really appreciate the effort. These real-workload results are very valuable for understanding how the different approaches behave in a KVM workload. The results also make the effect of the reader-free fastpath much clearer. In the measurements on both systems, it substantially reduces the average invalidation latency of synchronize_srcu_atomic() compared with the same implementation without the fastpath. You mentioned that the SRCU read side scales a lot better and avoids cacheline bouncing. If you happen to have any existing measurements of the reader side, such as throughput or reader-side latency, I would be very interested in seeing them. That would be useful for understanding the reader-side benefit you mentioned. Of course, no need to rerun anything just for this. I was mainly wondering whether you already had such data from the existing testing. Thanks again for all the help. If you notice anything else in this workload that would be interesting to look at, I'd be very happy to dig into it. Thanks, Kunwu
On Wed, 2026-09-23 at 23:58 +0800, KunWu Chan wrote: > > You mentioned that the SRCU read side scales a lot better and avoids > cacheline bouncing. If you happen to have any existing measurements of > the reader side, such as throughput or reader-side latency, I would be > very interested in seeing them. That would be useful for understanding > the reader-side benefit you mentioned. > > Of course, no need to rerun anything just for this. I was mainly > wondering whether you already had such data from the existing testing. Most of the KVM gfn-to-pfn-cache usage is per-vCPU so doesn't get much parallelism. The main case is interrupt delivery to Xen guests' event channels, and I did some benchmarking of parallel interrupt delivery. I'll see if I still have those results, or tell my friend to go and repeat some meaningful tests.
On Thu, Sep 24, 2026 at 12:07 AM David Woodhouse <dwmw2@infradead.org> wrote: > > On Wed, 2026-09-23 at 23:58 +0800, KunWu Chan wrote: > > > > You mentioned that the SRCU read side scales a lot better and avoids > > cacheline bouncing. If you happen to have any existing measurements of > > the reader side, such as throughput or reader-side latency, I would be > > very interested in seeing them. That would be useful for understanding > > the reader-side benefit you mentioned. > > > > Of course, no need to rerun anything just for this. I was mainly > > wondering whether you already had such data from the existing testing. > > Most of the KVM gfn-to-pfn-cache usage is per-vCPU so doesn't get much > parallelism. The main case is interrupt delivery to Xen guests' event > channels, and I did some benchmarking of parallel interrupt delivery. > I'll see if I still have those results, or tell my friend to go and > repeat some meaningful tests. Thanks David, that would be very helpful. The parallel interrupt delivery case sounds particularly interesting. Please don't go to any trouble if the old results are not available. I really appreciate you checking, and I also appreciate your friend's help with the measurements. Thanks again, Kunwu
On Thu, 2026-09-24 at 00:26 +0800, KunWu Chan wrote: > The parallel interrupt delivery case sounds particularly interesting. > Please don't go to any trouble if the old results are not available. The old results were on the original RCU-based (not SRCU) version, so I redid them with the latest, on the 192-way PREEMPT_RT GNR box. It's a bit of a microbenchmark: N vCPUs spinning in guest mode, with N more sender threads, each delivering interrupts as fast as it can to its own paired vCPU thread. The vCPU isn't even acknowledging the interrupt, but the locked btsl will still be dirtying the cache lines of the shared info evtchn_pending bitmap even to find that the bit is already set (qv). The rwlock version gets up to 8-9M deliveries per second and then starts to regress past about 32 parallel vCPUs. While SRCU starts off faster, and gets more so. Deliveries/sec, spread layout: ┌───────┬──────────┬─────────────┬───────┐ │ vCPUs │ rwlock │ atomic SRCU │ ratio │ ├───────┼──────────┼─────────────┼───────┤ │ 1 │ 1.02M │ 1.13M │ 1.1× │ ├───────┼──────────┼─────────────┼───────┤ │ 2 │ 1.87M │ 2.27M │ 1.2× │ ├───────┼──────────┼─────────────┼───────┤ │ 4 │ 3.59M │ 4.57M │ 1.3× │ ├───────┼──────────┼─────────────┼───────┤ │ 8 │ 7.06M │ 9.13M │ 1.3× │ ├───────┼──────────┼─────────────┼───────┤ │ 16 │ 8.75M │ 16.8M │ 1.9× │ ├───────┼──────────┼─────────────┼───────┤ │ 32 │ 8.52M │ 33.3M │ 3.9× │ ├───────┼──────────┼─────────────┼───────┤ │ 64 │ 6.75M │ 63.7M │ 9.4× │ └───────┴──────────┴─────────────┴───────┘ This is with the port numbers of each of the N CPUs deliberately spread out into different cache lines (which arguably we ought to do for production guests, but we don't). If I let them all pack with sequential port# allocation, it makes no difference to rwlock but the SRCU variant hits a scaling cliff around N=16 too (17.2M @32, 14.0M @64). But hey, as I said: microbenchmark.
On Thu, Sep 24, 2026 at 5:56 AM David Woodhouse <dwmw2@infradead.org> wrote: > > On Thu, 2026-09-24 at 00:26 +0800, KunWu Chan wrote: > > The parallel interrupt delivery case sounds particularly interesting. > > Please don't go to any trouble if the old results are not available. > > The old results were on the original RCU-based (not SRCU) version, so > I redid them with the latest, on the 192-way PREEMPT_RT GNR box. > > It's a bit of a microbenchmark: N vCPUs spinning in guest mode, with N > more sender threads, each delivering interrupts as fast as it can to > its own paired vCPU thread. The vCPU isn't even acknowledging the > interrupt, but the locked btsl will still be dirtying the cache lines > of the shared info evtchn_pending bitmap even to find that the bit is > already set (qv). > > The rwlock version gets up to 8-9M deliveries per second and then > starts to regress past about 32 parallel vCPUs. While SRCU starts off > faster, and gets more so. > > Deliveries/sec, spread layout: > ┌───────┬──────────┬─────────────┬───────┐ > │ vCPUs │ rwlock │ atomic SRCU │ ratio │ > ├───────┼──────────┼─────────────┼───────┤ > │ 1 │ 1.02M │ 1.13M │ 1.1× │ > ├───────┼──────────┼─────────────┼───────┤ > │ 2 │ 1.87M │ 2.27M │ 1.2× │ > ├───────┼──────────┼─────────────┼───────┤ > │ 4 │ 3.59M │ 4.57M │ 1.3× │ > ├───────┼──────────┼─────────────┼───────┤ > │ 8 │ 7.06M │ 9.13M │ 1.3× │ > ├───────┼──────────┼─────────────┼───────┤ > │ 16 │ 8.75M │ 16.8M │ 1.9× │ > ├───────┼──────────┼─────────────┼───────┤ > │ 32 │ 8.52M │ 33.3M │ 3.9× │ > ├───────┼──────────┼─────────────┼───────┤ > │ 64 │ 6.75M │ 63.7M │ 9.4× │ > └───────┴──────────┴─────────────┴───────┘ > > This is with the port numbers of each of the N CPUs deliberately spread > out into different cache lines (which arguably we ought to do for > production guests, but we don't). If I let them all pack with > sequential port# allocation, it makes no difference to rwlock but the > SRCU variant hits a scaling cliff around N=16 too (17.2M @32, 14.0M > @64). But hey, as I said: microbenchmark. Resend. Hi David, Thanks for taking the time to rerun this. This is exactly the kind of data I was hoping to get, and the scaling at 32 and 64 vCPUs is particularly useful. The cache-line layout comparison is also a useful data point. I'll keep the microbenchmark limitation in mind when using these results. Thanks again for the extra work. Thanks, Kunwu
On 23 September 2026 18:26:32 CEST, KunWu Chan <kunwu.chan@gmail.com> wrote: >On Thu, Sep 24, 2026 at 12:07 AM David Woodhouse <dwmw2@infradead.org> wrote: >> >> On Wed, 2026-09-23 at 23:58 +0800, KunWu Chan wrote: >> > >> > You mentioned that the SRCU read side scales a lot better and avoids >> > cacheline bouncing. If you happen to have any existing measurements of >> > the reader side, such as throughput or reader-side latency, I would be >> > very interested in seeing them. That would be useful for understanding >> > the reader-side benefit you mentioned. >> > >> > Of course, no need to rerun anything just for this. I was mainly >> > wondering whether you already had such data from the existing testing. >> >> Most of the KVM gfn-to-pfn-cache usage is per-vCPU so doesn't get much >> parallelism. The main case is interrupt delivery to Xen guests' event >> channels, and I did some benchmarking of parallel interrupt delivery. >> I'll see if I still have those results, or tell my friend to go and >> repeat some meaningful tests. > >Thanks David, that would be very helpful. > >The parallel interrupt delivery case sounds particularly interesting. >Please don't go to any trouble if the old results are not available. >I really appreciate you checking, and I also appreciate your friend's >help with the measurements. It's no trouble; my friend is remarkably compliant once I've held its methodology to account and probed at its conclusions.
On Thu, Sep 24, 2026 at 12:46 AM David Woodhouse <dwmw2@infradead.org> wrote: > > On 23 September 2026 18:26:32 CEST, KunWu Chan <kunwu.chan@gmail.com> wrote: > >On Thu, Sep 24, 2026 at 12:07 AM David Woodhouse <dwmw2@infradead.org> wrote: > >> > >> On Wed, 2026-09-23 at 23:58 +0800, KunWu Chan wrote: > >> > > >> > You mentioned that the SRCU read side scales a lot better and avoids > >> > cacheline bouncing. If you happen to have any existing measurements of > >> > the reader side, such as throughput or reader-side latency, I would be > >> > very interested in seeing them. That would be useful for understanding > >> > the reader-side benefit you mentioned. > >> > > >> > Of course, no need to rerun anything just for this. I was mainly > >> > wondering whether you already had such data from the existing testing. > >> > >> Most of the KVM gfn-to-pfn-cache usage is per-vCPU so doesn't get much > >> parallelism. The main case is interrupt delivery to Xen guests' event > >> channels, and I did some benchmarking of parallel interrupt delivery. > >> I'll see if I still have those results, or tell my friend to go and > >> repeat some meaningful tests. > > > >Thanks David, that would be very helpful. > > > >The parallel interrupt delivery case sounds particularly interesting. > >Please don't go to any trouble if the old results are not available. > >I really appreciate you checking, and I also appreciate your friend's > >help with the measurements. > > It's no trouble; my friend is remarkably compliant once I've held its methodology to account and probed at its conclusions. > Haha, fair enough. Thanks again to both of you for indulging me. :-)
© 2016 - 2026 Red Hat, Inc.