Re: [PATCH -rcu/dev 1/4] hazptrtorture: Release all deferred hazard pointers before stopping
From: Andrea Parri
Date: Tue Nov 03 2026 - 18:45:13 EST
On Tue, Nov 03, 2026 at 12:44:07PM -0800, Paul E. McKenney wrote:
> On Tue, Nov 03, 2026 at 08:05:06PM +0100, Andrea Parri wrote:
[...]
> > > hazptr_torture_cleanup() stops the kthreads in random order, which
> >
> > The order is fixed: do_pending, preempt, the writer, then the readers.
>
> That was my first thought, but then I remembered that torture_init_begin()
> sets fullstop to FULLSTOP_DONTSTOP, which causes torture_must_stop()
> to return true, thus stopping all the hazptrtorture kthread at about
> the same time in some random order.
>
> By the time hazptr_torture_cleanup() gets around to invoking
> torture_stop_kthread() for the various kthreads, the game is up.
torture_must_stop() does become true for all the kthreads at once,
when torture_cleanup_begin() sets FULLSTOP_RMMOD, but each, once out of
its loop, waits in torture_kthread_stopping() until
hazptr_torture_cleanup() calls kthread_stop() on it, in the order above.
[...]
> I instead dropped the torture_stop_kthread() reordering from the most
> recent version of this patch shown below. (Which still contains the
> above typos, but could you please check it otherwise?)
With the pass after torture_kthread_stopping(), each reader reaches that
pass only after kthread_stop() is called on it. Cleanup now waits for
the writer before making those calls:
/* hazptr_torture_cleanup(): */
torture_stop_kthread(hazptr_torture_writer, ...) /* waits */
torture_stop_kthread(hazptr_torture_reader, ...) /* releases */
So a writer waiting in ->sync() on a deferred hazard pointer left after
do_pending's last pass keeps kthread_stop() on it from returning, as in
the hang this patch fixes, and the readers are never stopped.
With ba9a3e4d3b237 and patches 2-4 on top (d0a4ec9443ee), both
3-minute PREEMPT runs with kthread_do_pending_ms=10000 hang this way:
after "Stopping hazptr_torture_writer task", the writer stays in
->sync(), no reader is stopped, and 3823 and 4072 deferred hazard
pointers are never released (reldefer - relundefer).
Keeping the reordering, or doing the pass right after the reader's
loop, before torture_kthread_stopping(), avoids this. Your previous
version, which keeps the reordering, passed those runs, as did the
variant from my earlier reply, which does both.
> > Also, "hazptrtorture: Nest a second hazard pointer in readers" conflicts
> > with moving hazptr_torture_do_one_pending() up, as both add a function
> > after hazptr_torture_defer(); keeping both resolves it.
>
> I believe that I have resolved that correctly, but could you please
> check v7.4-rc1..d0a4ec9443ee in my -rcu tree?
The resolution looks right to me: it keeps both functions, and the
patch adds and removes the same lines as in v1.
Thanks,
Andrea