On 2026-09-27 12:33, Bradley Morgan wrote:
On 27 September 2026 17:27:33 BST, Mathieu Desnoyers
<[email protected]> wrote:
On 2026-09-27 12:07, Bradley Morgan wrote:
On 27 September 2026 16:51:27 BST, Mathieu Desnoyers
<[email protected]> wrote:
Hi Paul,
This series applies on top of "hazptr: handle NULL address in
hazptr_detach" you have in your rcu dev tree.
This first patch addresses a race identified by Boqun Feng in the
two-phase wildcard scheme.
Patches 2-3 are prerequisites for using ptr_eq() in the 4th patch.
Those were discussed at length in a prior version of hazard pointer
patches.
Patch 4 introduces a "try acquire" helper to allow the fast path
to not rely on wildcards, while keeping the wildcard forward
progress guarantees in the acquire slow path, used on fast path
failure.
Hi, here is a hazptr perf test on powerpc
REAL kill_fasync(), ns per call, best of 3, 100k calls:
(stock = rwlock walk, conv = hazptr walk, same v3 tree ± the conversion)
shape stock conv delta
1 node, 1 walker 59 59 +0.0% (singleton: identical)
16 nodes, 1 walker 539 539 +0.0% (uncontended: identical)
16 nodes, 4 walkers 509 134 -73.7% ← rwlock readers contend
16 nodes, 8 walkers 313 113 -63.9% ← same list, 8 cpus
64 nodes, 1 walker 1979 2039 +3.0% (pure walk: hazptr tax)
64 nodes, 4 walkers 1914 509 -73.4%
64 nodes, 8 walkers 1015 382 -62.4%
Its SLOWER than rcu, but beats rwlock
Two feedback points:
1) The comparison I think Boqun cares mostly about is with expedited
RCU grace periods, this is where we suspect there is a significant
benefit to using hazptr rather than RCU to eliminate those IPIs
on synchronize.
It's good to know that it performs better than rwlock (albeit it's
not surprising).
2) I'm concerned about what looks like a use of hazptr to protect linked
lists elements in your benchmark (did I miss anything ?).
RCU read-side critical sections protect all elements of a linked list
naturally, but hazptr requires more care. See this comment above
hazptr_acquire:
* This protection is unconditional, and has limitations similar to
* that of unconditional reference-counter acquisition. In particular,
* although holding a hazard pointer prevents a hazard-pointer-protected
* object from being freed, it does not prevent that object from being
* removed from a linked data structure, and does not prevent other
* hazard-pointer-protected objects referenced by this object from being
* both removed and freed. At which point, invoking hazptr_acquire()
* on these dangling pointers would be a bug. On the other hand, use of
* hazptr_acquire() is safe for immortal pointers to objects that do not
* themselves contain pointers to hazard-pointer-protected objects.
* Other (more complex) use cases are also possible.
Does the pointer you protect qualify as an "immortal" pointer, or it's
a linked list "next" pointer ?
Hmm. Do you have a idea on what you could metaphorically convert, with a
core subsystem?
I'll give anything you want me to do a try
At a high level, I suspect it would be good to start by digging into
users of synchronize_rcu_expedited(), to see if a few of those may be
good candidates.
I would also favor scenarios where RCU (or locking) are used to protect
the existence of an object reachable from a global pointer, and use
hazptr to protect that object. Note that initially this precludes
a hazptr-protected list, because the next pointers would sit in
prior objects which are themselves hazptr-protected, which is not
sufficient to guarantee existence against a hand in hand traversal.
However, if you have a pointer to an object "side-car" structure
(e.g. optional extra metadata), and the object containing the pointer
is guaranteed to exist by another mechanism (e.g. RCU, locking), then
that pointer-to-side-car-object field would be a good candidate for
hazptr (AFAIU).
I'm not saying the linked lists could not be done, but it would require
more care.
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com