Re: [RFC PATCH v5 1/2] hazptr: Implement Hazard Pointers
From: Paul E. McKenney
Date: Sat Jun 27 2026 - 00:14:42 EST
On Fri, Jun 26, 2026 at 11:56:13PM -0400, Mathieu Desnoyers wrote:
> On 2026-06-26 19:06, Paul E. McKenney wrote:
> > [ Trimming CC. ]
> >
> > On Mon, Feb 23, 2026 at 03:44:17PM -0500, Mathieu Desnoyers wrote:
> > > This API provides existence guarantees of objects through Hazard
> > > Pointers [1] (hazptr).
> > >
> > > Its main benefit over RCU is that it allows fast reclaim of
> > > HP-protected pointers without needing to wait for a grace period.
> > >
> > > This implementation has 4 statically allocated hazard pointer slots per
> > > cpu for the fast path, and relies on a on-stack backup slot allocated by
> > > the hazard pointer user as fallback in case no per-cpu slot is
> > > available.
> > >
> > > It integrates with the scheduler to migrate per-CPU slots to the backup
> > > slot on context switch. This ensures that the per-CPU slots won't be
> > > used by blocked or preempted tasks holding on hazard pointers for a long
> > > time.
> > >
> > > References:
> > >
> > > [1]: M. M. Michael, "Hazard pointers: safe memory reclamation for
> > > lock-free objects," in IEEE Transactions on Parallel and
> > > Distributed Systems, vol. 15, no. 6, pp. 491-504, June 2004
> >
> > I (finally) put together a stress test for this, which is the following
> > commits on -rcu:
> >
> > bfb239e036d616 torture: Add a hazptrtorture.c torture test
> > adda38c3cffcd6 hazptrtorture: Add testing of on-stack hazptr_ctx structures
> > 311e199e482873 hazptrtorture: Add microsecond-scale sleep in readers
> > 21ccb41f79a45b hazptrtorture: Enable system-independent CPU overcommit
> > 82e8c141265c81 torture: Add a stutter_will_wait() function
> > 9ad8169bd3a367 hazptrtorture: Use mnemonic local variables for context information
> > cd541d5eb7347f hazptrtorture: Split hazptr_torture_reader_tail() from hazptr_torture_reader()
> > 0de8bda6b00051 hazptrtorture: Add kthread to release deferred hazard pointers
> > 3deefef00acb22 hazptrtorture: Defer release of hazard pointers
> > 65b2cf3c6ea34e hazptrtorture: Add irq_acquire to acquire hazptr from irq
> > 98d334c04b58fe hazptrtorture: Use task_state_to_char() for task-state reporting
> > 1e89aae50a3fde hazptrtorture: Pass hazptr_pending to hazptr_torture_reader_tail()
> > 4b1a177190e2e1 hazptrtorture: Add the ability to disable the writer kthread
> > 2c966f58358329 hazptrtorture: Add irq_release to release hazptr from irq
> > 16258269b41ed3 hazptrtorture: Accumulate operation statistics
> > c090e2659abcb3 doc: Add hazptrtorture module parameters
> >
> > Initial runs suggest that hazard pointers cannot be acquired by one
> > task and released by another. Is that expected behavior, or is my test
> > improperly passing the hazard pointers? If the latter, we should of
> > course document the proper hazard-pointer-passing mechanism.
>
> This is unexpected. I've looked at your test code quickly and could
> not figure out what's wrong though. But it's late. How do you observe
> that it fails ?
Not an emergency, so your schedule is my schedule. Especially given
that I am mostly taking this coming week off. And that it took me such
a long time to get this torture test done. ;-)
I run either scenario (PREEMPT or NOPREEMPT) with:
--bootarg "hazptrtorture.onoff_interval=3333 hazptrtorture.stat_interval=15"
I get the following on the console, and things go downhill from there.
I get the same thing when I turn off CPU hotplug, for whatever that is
worth.
Thanx, Paul
[ 6.872932] Oops: general protection fault, probably for non-canonical address 0xdead000000000110: 0000 [#1] SMP PTI
[ 6.874626] CPU: 4 UID: 0 PID: 136 Comm: hazptr_torture_ Not tainted 7.1.0-rc4-00070-g8b866e80f23c #1484 PREEMPT(full)
[ 6.876268] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014
[ 6.877411] RIP: 0010:hazptr_synchronize_overflow_list+0x3e/0x90
[ 6.878287] Code: 08 48 89 c6 48 85 db 74 54 4d 8b 65 10 eb 1b e8 d8 11 fa 00 f3 90 4c 89 ef e8 de 13 fa 00 48 89 c6 49 8b 45 10 4c 39 e0 75 41 <48> 8b 43 10 4c 89 ef 48 39 e8 74 d9 48 83 f8 01 74 d3 e8 ab 11 fa
[ 6.881146] RSP: 0000:ffffbaf7c04ffe60 EFLAGS: 00010086
[ 6.881938] RAX: 0000000000000276 RBX: dead000000000100 RCX: 0000000000000003
[ 6.883028] RDX: 0000000000000001 RSI: 0000000000000286 RDI: ffffa084df4980e0
[ 6.884119] RBP: ffffffffb72031c0 R08: 00000000002547d1 R09: 0000000000000004
[ 6.885153] R10: 0000000000000001 R11: ffffa084df31c328 R12: 0000000000000276
[ 6.886202] R13: ffffa084df4980e0 R14: ffffffffb72031c0 R15: ffffa084df4980c0
[ 6.887213] FS: 0000000000000000(0000) GS:ffffa0852818f000(0000) knlGS:0000000000000000
[ 6.888301] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 6.889061] CR2: 0000000000000000 CR3: 0000000007430000 CR4: 00000000000006f0
[ 6.890041] Call Trace:
[ 6.890408] <TASK>
[ 6.890725] hazptr_synchronize+0xd1/0x130
[ 6.891303] hazptr_torture_writer+0x180/0x3f0
[ 6.891921] ? __pfx_hazptr_torture_writer+0x10/0x10
[ 6.892613] kthread+0xe5/0x120
[ 6.893077] ? __pfx_kthread+0x10/0x10
[ 6.893612] ret_from_fork+0x1bd/0x220
[ 6.894155] ? __pfx_kthread+0x10/0x10
[ 6.894690] ret_from_fork_asm+0x1a/0x30
[ 6.895226] </TASK>
[ 6.895562] Modules linked in:
[ 6.895958] ---[ end trace 0000000000000000 ]---