Re: [RFC PATCH 00/12] RCU pseudo-transactions
From: Mathieu Desnoyers
Date: Tue Oct 27 2026 - 21:13:53 EST
On 2026-10-27 15:57, Mathieu Desnoyers wrote:
[...]
E) Use a preallocated per-cpu rcu-txn slab, synchronize txn descriptor reclaim with
RCU (steady state) and hazard pointers (OOM)
This is basically just pushing idea (D) further to remove the need for sleepable callers.
We surround the rcu txn proxy pointer resolve with both a RCU read-side critical section
and a hazard pointer slab address guard, thus protecting the use of the txn descriptor
with two types of critical sections. The resolve would run with interrupts disabled.
The "resolve" path of txn proxy is not a fast path, so we don't mind the extra overhead
too much.
On the "remove" side, we typically have plenty of preallocated rcu-txn from the slab.
In the common case, we keep using RCU deferral to free the rcu-txn in batches. This
would implement a custom per-cpu pending list to enable the following "stealing"
scheme.
In the rare cases where a user empties the slab, we move to a more aggressive
mechanism based on synchronize_hazptr: we "steal" the batched in-flight RCU txn
reclaims so we can fast-track their reclaim after a hazptr synchronize. This would
all be using busy-wait and the only contexts we'd wait against have irqs disabled.
The motivation for handling the steady-state with RCU is throughput (no synchronize_hazptr
on the typical "remove" case). Hazard pointers then handle the OOM corner case without
requiring sleepable callers.
Well it turns out that this approach has potential, but the hazard pointer
machinery is way overkill for this. We can replace my use of hazptr above by
a very simple RCU domain with the following characteristics:
- All RCU txn proxy resolves are RCU readers running with irqoff, protected by a
per-cpu counter (incremented on read lock and again on unlock),
- There is at most one reader per cpu at any time,
- We use a synchronize RCU on that domain on OOM for the pending slab reclaim
"steal" to do reclaim synchronously. This domain's synchronize RCU waits for
each CPU until it observes either an even counter or a counter transition.
- We disable preemption across rcu txn (e.g. list insert, remove).
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 ?
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com