Re: [PATCH] mm/mmu_notifier: Remove non_block_start/end() from notifier invocation

David Woodhouse <[email protected]>
Newsgroups dev.linux.lists.linux-rt-devel,org.kernel.vger.kvm,org.kernel.vger.linux-kernel,org.kvack.linux-mm
Message-ID <[email protected]>
On Wed, 2026-08-12 at 00:50 +0100, David Woodhouse wrote:
> On Tue, 2026-08-11 at 15:58 -0700, Sean Christopherson wrote:
> >  SRCU is
> > fantastic infrastructure, but I genuinely think it's not the right fit here,
> > especially since we'll likely need a different solution for in-guest readers
> > anyways.

Actually I think it fits quite nicely into the GPC SRCU model. We add a
GUEST_USING_GPC flag to the gpc->state atomic. A vCPU which is going to
use the GPC in guest mode will do an atomic cmpxchg to set
GUEST_USING_GPC while the GPC_VALID flag is still set.

And then in the flush side, *exactly* the same loop which already sets
'cleared' when a cache has GPC_VALID, will also spot that
GUEST_USING_GPC and add the corresponding vCPU to the bitmask of vCPUs
to be kicked.

It's a perfect fit.

In fact, we could observe that the GUEST_USES_GPC concept has *always*
been closer to the RCU model of "readers do as they like; the writer
has to wait until they're done".

It was mixing that with rwlock that was odd.

> The cases where we have to hold the host physical address *during* the
> time we enter guest mode to run a vCPU were never covered by the rwlock
> either.
> 
> Fred's patches which reinstate that GUEST_USES_GPC mode are kicking the
> vCPU from the invalidate_start handler, just as the original
> implementation did. However the locking (or RCU) for the in-kernel
> users ends up changing, I don't see the in-guest part changing.
> 
> Unless you're imagining some scheme which could handle both? But the
> in-kernel readers are *brief* and will always go away on their own,
> while the in-guest needs to be kicked; they are opposites.

Honestly, if we're going to start re-inventing concurrency primitives
just because "SRCU *can* be used badly", even though we weren't *going*
to use SRCU badly in this case... maybe I should revisit my starting
assumption when I first started digging into this, which was that
"nobody wants a raw_rwlock_t as a workaround to the RT issues".

And if we want to invent new primitives, because that's *always* a
barrel of laughs, maybe we *could* try to build something really
dedicated to this use case...

Since every access is at least tenuously associated with *a* vCPU, we
could have a spinlock per vCPU and each read side takes "its own" while
the flush side takes all of them in turn, one at a time. That probably
only needs one such spinlock per vCPU (not per-GPC per-vCPU).

But maybe we can handle the GUEST_USES_GPC mode too... instead of a
spinlock, have an atomic_t of the number of readers, with a high bit
indicating that it's in-guest.... but honestly, I just don't want to.

SRCU is *fine* here. Let's not overcomplicate things.

> > > I get it. RCU is a versatile tool, and in *some* cases the *Sleepable*
> > > variant of RCU gets used in ways which would cause grace period latencies
> > > which are thoroughly unacceptable in an MMU notifier callback.
> > > 
> > > But in the specific case of a dedicated kvm->gpc_srcu whose only
> > > readers are tiny snippets of code that until today were always run with
> > > rwlock_irqsave? That is *not* Jason's worst-case bugbear. It's fine.
> > 
> > I agree it's more than likely fine for your use case, I'm not convinced it'll be
> > fine for use cases that heavily overcommit memory, or do NUMA balancing, or (close
> > your eyes) enable KSM.
> > 
> > E.g. it doesn't take all that much for even a single expedited sync to generate
> > a delay of 20ms.
> > https://lore.kernel.org/all/[email protected]
> 
> That looks to me like a pathological case where KVM is trying to use a
> single srcu_struct in two different modes, and getting sad when they
> conflict. That would never be the case for the separate gpc_srcu.
> 
> I've been playing with the soak tests, running in parallel with a load
> of about 140, with KASAN/lockdep/etc enabled.
> 
> I also implemented that thing I suggested: a try_synchronize_srcu()
> which doesn't even use the waitqueue when it can trivially determine
> that it doesn't need to wait.
> 
> Even when we're stressing invalidation vs readers, it ends up taking
> the fast path in about 99% of cases, taking around 4-16µs for those;
> 32-128µs when it does need to call srcu_synchronize_expedited().
> 
> It goes above 8ms in 4.4ppm of cases, with the p100 outlier being
> 17.6ms. My gut tells me we'd see those occasional outliers even with
> the rwlock at this load, but I'm going to kick that test off and answer
> that definitively in the morning.

That one crashed (reminding us that I was actually doing this to fix
*bugs* not just chase the last bits of performance). A rerun this
morning shows a p100 latency of ~11ms for the rwlock case too.

I redid the tests to also track the costs of the *other* thing that 
the KVM mmu_notifier does; poking pages out of the EPT and kicking
vCPUs. The p100 there was only about 2½ms for both EPT and shadow
paging mode. I wasn't able to test with ATS+PASID capable devices,
which I suspect would have led to larger numbers :)

Really, I just don't think Jason's tail-latency bugbear is actually
anything to be scared of. It's not new, and it's not dramatically
different.
smime.p7s (application/pkcs7-signature, 6 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.