Re: [RFC PATCH 00/12] RCU pseudo-transactions

From: Paul E. McKenney

Date: Mon Nov 09 2026 - 20:44:06 EST


On Mon, Nov 09, 2026 at 08:00:12PM -0500, Mathieu Desnoyers wrote:
> On 2026-11-09 19:25, Paul E. McKenney wrote:
> > On Tue, Oct 27, 2026 at 09:13:17PM -0400, Mathieu Desnoyers wrote:
> [...]
> >> So we'd keep using call_rcu to handle the steady-state reclaim of rcu
> txn,
> >> but use this specialized irqoff RCU domain for the empty slab case.
> >>
> >> Thoughts ?
> >
> > Atomic SRCU within interrupts-disabled regions seems to fit
> > this bill: synchronize_srcu_atomic(), srcu_read_lock_atomic(),
> > and srcu_read_unlock_atomic(), which interrupts disabled across
> > the latter two. Maybe srcu_read_lock_atomic_irqsave() and
> > srcu_read_lock_atomic_irqrestore() if that helps.
> >
> > Or am I missing a turn in your requirements?
>
> It fits well, thanks! It would replace the per-CPU counters I wrote
> for this domain. The steady state stays on call_rcu(), so the
> srcu_struct would only see synchronize_srcu_atomic(), never
> call_srcu(). I see two gaps between my requirements and your
> proposal:
>
> First, NMI readers. rcu_txn_dereference() should work in any context,
> NMI included, as rcu_dereference() does. A tracer or a BPF program can
> walk an rcu_txn list from NMI. The atomic flavor uses
> __srcu_read_lock(). Its this_cpu_inc() is not NMI-safe on every
> architecture. And one srcu_struct cannot mix the atomic flavor with
> the nmisafe one.
>
> Could the atomic flavor count its readers as srcu_read_lock_nmisafe()
> does? Then a reader could also enter from NMI. The code I have for the
> next version keeps one counter per NMI nesting level for this. With
> SRCU, the sums of locks and unlocks handle the nesting already.

The other user that I know of is David Woodhouse, now CCed.

David, would you be OK with srcu_read_lock_atomic() using NMI-safe
counters, similar to __srcu_read_lock_fast()?

(Yes, I *could* make only your _irqsave() and _irqrestore() variants
NMI-safe, but then we have to enforce different srcu_struct structures
for _irqsave() and not.)

> Second, interrupts off. The wait for readers can run with interrupts
> disabled, for example in a list delete under a raw spinlock. The
> kerneldoc of synchronize_srcu_atomic() then requires the readers
> to disable interrupts too. So yes, the irqsave and irqrestore variants
> would help. The readers would use them instead of preemption off.
>
> Would you prefer to add these two variants on the SRCU side, or should
> I prototype them with the next version of this series?

Your choice!

If you would like to do it, the trick is to make srcu_read_lock_atomic()
and srcu_read_unlock_atomic() invoke __srcu_read_lock_fast() and
__srcu_read_unlock_fast(), respectively, instead of __srcu_read_lock()
and __srcu_read_unlock(), again respectively.

Then there would need to be an srcu_read_lock_atomic_irqsafe() and
srcu_read_unlock_irqrestore(), which would (as you say), replace
preempt_disable() with local_irq_save() and preempt_enable()
with local_irq_restore(). There would be a flags argument that
as far as I know requires srcu_read_lock_atomic_irqsafe() and
srcu_read_unlock_irqrestore() be macros. It would be good to share code
with srcu_read_lock_atomic() and srcu_read_unlock_atomic().

And kernel/rcu/rcutorture.c would need a bit of tweaking to test
this new interface, which should be discoverable by looking for
the code that tests srcu_read_{,un}lock_atomic(). Maybe just make
srcu_torture_read_lock() randomly decide between srcu_read_lock_atomic()
and srcu_read_lock_atomic_irqsave(), and have srcu_torture_read_unlock()
follow that decision.

One potentially tricky part here is that rcutorture is not set up to
pass a flags variable from a read-lock to the corresponding read-unlock.

Thanx, Paul