* [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping
@ 2026-10-19 16:20 Andrea Parri
2026-10-19 16:22 ` Bradley Morgan
2026-10-20 18:49 ` Paul E. McKenney
0 siblings, 2 replies; 7+ messages in thread
From: Andrea Parri @ 2026-10-19 16:20 UTC (permalink / raw)
To: Paul E. McKenney
Cc: Andrea Parri, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Bradley Morgan, Kunwu Chan, rcu, linux-kernel
hazptrtorture can hang at shutdown when deferral is enabled, as in the
PREEMPT scenario: the writer stays in ->sync() and kthread_stop() on it
never returns, until kvm.sh kills QEMU:
[ 1800.899278] hazptr-torture: Stopping hazptr_torture_do_pending task
[ 1800.899447] hazptr-torture: Stopping hazptr_torture_writer task
[ 1812.713870] hazptr-torture: rtc: 00000000225df70a ver: 12436 HTWS_SYNC tfle: 0 rta: 12437 rtaf: 0 rtf: 12427 onoff: 48783/48783:48786/48786 3,254:3,280 611671:731494 (HZ=1000) acq: 5720353149 rel: 5720210186 acqirq: 571927 relirq: 714778 reldefer: 714139 relundefer 714114
[ 1812.713971] hazptr-torture: hazptr_torture_stats is stopping
Summary: Potential hang (QEMU killed)
!!! PID 1393523 hung at 1980 vs. 1800 seconds
hazptr_torture_cleanup() stops the do_pending kthread before the writer
and the readers. Once torture_must_stop(), do_pending makes one last
pass and leaves its loop, but unless stutter_will_wait(), that pass
releases the deferred hazard pointers of a single CPU.
Readers can also still defer after that pass, from the iteration they
are in when torture_must_stop() becomes true. Stopped readers hold no
hazard pointer, so the writer waits on one of the 25 deferred hazard
pointers above (reldefer - relundefer) that nothing releases.
Keep do_pending running until hazptr_torture_cleanup() stops it, after
the writer and the readers, releasing the deferred hazard pointers of
all CPUs on each pass once torture_must_stop() and once more on exit.
It now also sleeps between those passes, and kthread_stop() wakes it.
This should be safe because readers defer only from their own loop,
which they have left once torture_stop_kthread() returns for them, and
the hazptr_torture_acquire() IPI runs synchronously within that loop.
With this change, a 30-minute PREEMPT run on x86_64 with 8 CPUs ends
with "End of test: SUCCESS" and with as many hazard pointers released
from the pending lists as were deferred (reldefer: 960658 relundefer
960658).
Fixes: f23d7b47ced9 ("hazptrtorture: Add kthread to release deferred hazard pointers")
Assisted-by: LLM
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
---
kernel/rcu/hazptrtorture.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/kernel/rcu/hazptrtorture.c b/kernel/rcu/hazptrtorture.c
index 7c8b5899fb011..5153720074644 100644
--- a/kernel/rcu/hazptrtorture.c
+++ b/kernel/rcu/hazptrtorture.c
@@ -547,18 +547,25 @@ static int hazptr_torture_do_pending(void *arg)
DEFINE_TORTURE_RANDOM(rand);
VERBOSE_TOROUT_STRING("hazptr_torture_do_pending task started");
- do {
- if (stutter_will_wait()) {
+ /*
+ * Run until hazptr_torture_cleanup() stops this kthread, not just
+ * until torture_must_stop(): the writer can be waiting in ->sync()
+ * for a deferred hazard pointer while it is being stopped.
+ */
+ while (!kthread_should_stop()) {
+ if (torture_must_stop() || stutter_will_wait()) {
for_each_possible_cpu(cpu)
hazptr_torture_do_one_pending(cpu, &rand);
} else {
cpu = cpumask_next_wrap(cpu, cpu_possible_mask);
hazptr_torture_do_one_pending(cpu, &rand);
}
- if (!torture_must_stop())
- torture_hrtimeout_ms(kthread_do_pending_ms, USEC_PER_MSEC, &rand);
+ torture_hrtimeout_ms(kthread_do_pending_ms, USEC_PER_MSEC, &rand);
// Omit stutter_wait() because this function needs to do cleanup.
- } while (!torture_must_stop());
+ }
+ /* The readers have stopped, so nothing new can be deferred. */
+ for_each_possible_cpu(cpu)
+ hazptr_torture_do_one_pending(cpu, &rand);
torture_kthread_stopping("hazptr_torture_do_pending");
return 0;
}
@@ -773,7 +780,6 @@ hazptr_torture_cleanup(void)
return;
}
- torture_stop_kthread(hazptr_torture_do_pending, do_pending_task);
torture_stop_kthread(hazptr_torture_preempt, preempt_task);
torture_stop_kthread(hazptr_torture_writer, writer_task);
@@ -785,6 +791,12 @@ hazptr_torture_cleanup(void)
reader_tasks = NULL;
}
+ /*
+ * Stop do_pending only after the writer and the readers: the writer
+ * may be waiting on hazard pointers that readers deferred.
+ */
+ torture_stop_kthread(hazptr_torture_do_pending, do_pending_task);
+
torture_stop_kthread(hazptr_torture_stats, stats_task);
/* Do torture-type-specific cleanup operations. */
--
2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping
2026-10-19 16:20 [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping Andrea Parri
@ 2026-10-19 16:22 ` Bradley Morgan
2026-10-19 17:32 ` Andrea Parri
2026-10-20 18:49 ` Paul E. McKenney
1 sibling, 1 reply; 7+ messages in thread
From: Bradley Morgan @ 2026-10-19 16:22 UTC (permalink / raw)
To: Andrea Parri, Paul E. McKenney
Cc: Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Josh Triplett, Boqun Feng, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Kunwu Chan, rcu,
linux-kernel
On 19 October 2026 17:20:03 BST, Andrea Parri <parri.andrea@gmail.com>
wrote:
>hazptrtorture can hang at shutdown when deferral is enabled, as in the
>PREEMPT scenario: the writer stays in ->sync() and kthread_stop() on it
>never returns, until kvm.sh kills QEMU:
>
> [ 1800.899278] hazptr-torture: Stopping hazptr_torture_do_pending task
> [ 1800.899447] hazptr-torture: Stopping hazptr_torture_writer task
> [ 1812.713870] hazptr-torture: rtc: 00000000225df70a ver: 12436 HTWS_SYNC tfle: 0 rta: 12437 rtaf: 0 rtf: 12427 onoff: 48783/48783:48786/48786 3,254:3,280 611671:731494 (HZ=1000) acq: 5720353149 rel: 5720210186 acqirq: 571927 relirq: 714778 reldefer: 714139 relundefer 714114
> [ 1812.713971] hazptr-torture: hazptr_torture_stats is stopping
>
> Summary: Potential hang (QEMU killed)
> !!! PID 1393523 hung at 1980 vs. 1800 seconds
>
>hazptr_torture_cleanup() stops the do_pending kthread before the writer
>and the readers. Once torture_must_stop(), do_pending makes one last
>pass and leaves its loop, but unless stutter_will_wait(), that pass
>releases the deferred hazard pointers of a single CPU.
>
>Readers can also still defer after that pass, from the iteration they
>are in when torture_must_stop() becomes true. Stopped readers hold no
>hazard pointer, so the writer waits on one of the 25 deferred hazard
>pointers above (reldefer - relundefer) that nothing releases.
>
>Keep do_pending running until hazptr_torture_cleanup() stops it, after
>the writer and the readers, releasing the deferred hazard pointers of
>all CPUs on each pass once torture_must_stop() and once more on exit.
>It now also sleeps between those passes, and kthread_stop() wakes it.
>
>This should be safe because readers defer only from their own loop,
>which they have left once torture_stop_kthread() returns for them, and
>the hazptr_torture_acquire() IPI runs synchronously within that loop.
>
>With this change, a 30-minute PREEMPT run on x86_64 with 8 CPUs ends
>with "End of test: SUCCESS" and with as many hazard pointers released
>from the pending lists as were deferred (reldefer: 960658 relundefer
>960658).
>
>Fixes: f23d7b47ced9 ("hazptrtorture: Add kthread to release deferred hazard pointers")
>Assisted-by: LLM
Why not put this into a series?
>Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
>---
> kernel/rcu/hazptrtorture.c | 24 ++++++++++++++++++------
> 1 file changed, 18 insertions(+), 6 deletions(-)
>
>diff --git a/kernel/rcu/hazptrtorture.c b/kernel/rcu/hazptrtorture.c
>index 7c8b5899fb011..5153720074644 100644
>--- a/kernel/rcu/hazptrtorture.c
>+++ b/kernel/rcu/hazptrtorture.c
>@@ -547,18 +547,25 @@ static int hazptr_torture_do_pending(void *arg)
> DEFINE_TORTURE_RANDOM(rand);
>
> VERBOSE_TOROUT_STRING("hazptr_torture_do_pending task started");
>- do {
>- if (stutter_will_wait()) {
>+ /*
>+ * Run until hazptr_torture_cleanup() stops this kthread, not just
>+ * until torture_must_stop(): the writer can be waiting in ->sync()
>+ * for a deferred hazard pointer while it is being stopped.
>+ */
Could this be shorter?
>+ while (!kthread_should_stop()) {
>+ if (torture_must_stop() || stutter_will_wait()) {
> for_each_possible_cpu(cpu)
> hazptr_torture_do_one_pending(cpu, &rand);
> } else {
> cpu = cpumask_next_wrap(cpu, cpu_possible_mask);
> hazptr_torture_do_one_pending(cpu, &rand);
> }
>- if (!torture_must_stop())
>- torture_hrtimeout_ms(kthread_do_pending_ms, USEC_PER_MSEC, &rand);
>+ torture_hrtimeout_ms(kthread_do_pending_ms, USEC_PER_MSEC, &rand);
> // Omit stutter_wait() because this function needs to do cleanup.
>- } while (!torture_must_stop());
>+ }
>+ /* The readers have stopped, so nothing new can be deferred. */
>+ for_each_possible_cpu(cpu)
Is the comment needed? I don't know if it's nessesary.
>+ hazptr_torture_do_one_pending(cpu, &rand);
> torture_kthread_stopping("hazptr_torture_do_pending");
> return 0;
> }
>@@ -773,7 +780,6 @@ hazptr_torture_cleanup(void)
> return;
> }
>
>- torture_stop_kthread(hazptr_torture_do_pending, do_pending_task);
> torture_stop_kthread(hazptr_torture_preempt, preempt_task);
> torture_stop_kthread(hazptr_torture_writer, writer_task);
>
>@@ -785,6 +791,12 @@ hazptr_torture_cleanup(void)
> reader_tasks = NULL;
> }
>
>+ /*
>+ * Stop do_pending only after the writer and the readers: the writer
>+ * may be waiting on hazard pointers that readers deferred.
>+ */
May we shorten this? Feel free to bikeshed that one.
>+ torture_stop_kthread(hazptr_torture_do_pending, do_pending_task);
>+
> torture_stop_kthread(hazptr_torture_stats, stats_task);
>
> /* Do torture-type-specific cleanup operations. */
>
>
--- Thanks!
"I'm not a very positive person" - Linus torvalds
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping
2026-10-19 16:22 ` Bradley Morgan
@ 2026-10-19 17:32 ` Andrea Parri
2026-10-20 18:36 ` Paul E. McKenney
0 siblings, 1 reply; 7+ messages in thread
From: Andrea Parri @ 2026-10-19 17:32 UTC (permalink / raw)
To: Bradley Morgan
Cc: Andrea Parri, Paul E. McKenney, Frederic Weisbecker,
Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
Lai Jiangshan, Zqiang, Kunwu Chan, rcu, linux-kernel
On Mon, Oct 19, 2026 at 05:22:54PM +0100, Bradley Morgan wrote:
> On 19 October 2026 17:20:03 BST, Andrea Parri <parri.andrea@gmail.com>
> wrote:
[...]
> >Fixes: f23d7b47ced9 ("hazptrtorture: Add kthread to release deferred hazard pointers")
> >Assisted-by: LLM
>
> Why not put this into a series?
The two patches fix unrelated bugs, touch different files, and apply in
either order, so I posted them separately. But both are for -rcu/dev,
and the test notes in the hazptr patch rely on this one. I'll send the
next version as a two-patch series with this patch first, unless Paul
prefers separate submissions.
[...]
> >+ /*
> >+ * Run until hazptr_torture_cleanup() stops this kthread, not just
> >+ * until torture_must_stop(): the writer can be waiting in ->sync()
> >+ * for a deferred hazard pointer while it is being stopped.
> >+ */
>
> Could this be shorter?
Yes. The comment in hazptr_torture_cleanup() already says why, so this
one can just point there:
/* Keep going until hazptr_torture_cleanup() stops us, see there. */
[...]
> >+ /* The readers have stopped, so nothing new can be deferred. */
> >+ for_each_possible_cpu(cpu)
>
> Is the comment needed? I don't know if it's nessesary.
I'd keep it. A reader can defer after the last pass in the loop, and
kthread_stop() can then end the loop without another pass, so this
pass is needed; the comment says why one pass is enough.
> >+ /*
> >+ * Stop do_pending only after the writer and the readers: the writer
> >+ * may be waiting on hazard pointers that readers deferred.
> >+ */
>
> May we shorten this? Feel free to bikeshed that one.
Sure:
/* The writer may wait on hazard pointers that readers deferred. */
Thanks for the review,
Andrea
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping
2026-10-19 17:32 ` Andrea Parri
@ 2026-10-20 18:36 ` Paul E. McKenney
2026-10-20 18:40 ` Bradley Morgan
0 siblings, 1 reply; 7+ messages in thread
From: Paul E. McKenney @ 2026-10-20 18:36 UTC (permalink / raw)
To: Andrea Parri
Cc: Bradley Morgan, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Kunwu Chan, rcu, linux-kernel
On Mon, Oct 19, 2026 at 07:32:28PM +0200, Andrea Parri wrote:
> On Mon, Oct 19, 2026 at 05:22:54PM +0100, Bradley Morgan wrote:
> > On 19 October 2026 17:20:03 BST, Andrea Parri <parri.andrea@gmail.com>
> > wrote:
>
> [...]
>
> > >Fixes: f23d7b47ced9 ("hazptrtorture: Add kthread to release deferred hazard pointers")
> > >Assisted-by: LLM
> >
> > Why not put this into a series?
>
> The two patches fix unrelated bugs, touch different files, and apply in
> either order, so I posted them separately. But both are for -rcu/dev,
> and the test notes in the hazptr patch rely on this one. I'll send the
> next version as a two-patch series with this patch first, unless Paul
> prefers separate submissions.
I am fine either way. But whatever you do, please do *not* put them
into the same patch. ;-)
> [...]
>
> > >+ /*
> > >+ * Run until hazptr_torture_cleanup() stops this kthread, not just
> > >+ * until torture_must_stop(): the writer can be waiting in ->sync()
> > >+ * for a deferred hazard pointer while it is being stopped.
> > >+ */
> >
> > Could this be shorter?
>
> Yes. The comment in hazptr_torture_cleanup() already says why, so this
> one can just point there:
>
> /* Keep going until hazptr_torture_cleanup() stops us, see there. */
>
> [...]
The longer one is better.
> > >+ /* The readers have stopped, so nothing new can be deferred. */
> > >+ for_each_possible_cpu(cpu)
> >
> > Is the comment needed? I don't know if it's nessesary.
>
> I'd keep it. A reader can defer after the last pass in the loop, and
> kthread_stop() can then end the loop without another pass, so this
> pass is needed; the comment says why one pass is enough.
>
> > >+ /*
> > >+ * Stop do_pending only after the writer and the readers: the writer
> > >+ * may be waiting on hazard pointers that readers deferred.
> > >+ */
> >
> > May we shorten this? Feel free to bikeshed that one.
>
> Sure:
>
> /* The writer may wait on hazard pointers that readers deferred. */
And same here.
I am sure that it is possible to create shorter versions that keep all
to the information, but I am OK with Andrea's original versions.
Bradley, Andrea is not a native English speaker and I believe that
you are, so if you want better wording here, please provide it to him.
Perhaps someday he will return the favor should you ever be required to
write in Italian (or German or Ladin, for that matter). ;-)
Thanx, Paul
> Thanks for the review,
> Andrea
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping
2026-10-20 18:36 ` Paul E. McKenney
@ 2026-10-20 18:40 ` Bradley Morgan
0 siblings, 0 replies; 7+ messages in thread
From: Bradley Morgan @ 2026-10-20 18:40 UTC (permalink / raw)
To: paulmck, Paul E. McKenney, Andrea Parri
Cc: Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Josh Triplett, Boqun Feng, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Kunwu Chan, rcu,
linux-kernel
On 20 October 2026 19:36:47 BST, "Paul E. McKenney" <paulmck@kernel.org>
wrote:
>On Mon, Oct 19, 2026 at 07:32:28PM +0200, Andrea Parri wrote:
>> On Mon, Oct 19, 2026 at 05:22:54PM +0100, Bradley Morgan wrote:
>> > On 19 October 2026 17:20:03 BST, Andrea Parri <parri.andrea@gmail.com>
>> > wrote:
>>
>> [...]
>>
>> > >Fixes: f23d7b47ced9 ("hazptrtorture: Add kthread to release deferred
>hazard pointers")
>> > >Assisted-by: LLM
>> >
>> > Why not put this into a series?
>>
>> The two patches fix unrelated bugs, touch different files, and apply in
>> either order, so I posted them separately. But both are for -rcu/dev,
>> and the test notes in the hazptr patch rely on this one. I'll send the
>> next version as a two-patch series with this patch first, unless Paul
>> prefers separate submissions.
>
>I am fine either way. But whatever you do, please do *not* put them
>into the same patch. ;-)
>
>> [...]
>>
>> > >+ /*
>> > >+ * Run until hazptr_torture_cleanup() stops this kthread, not just
>> > >+ * until torture_must_stop(): the writer can be waiting in ->sync()
>> > >+ * for a deferred hazard pointer while it is being stopped.
>> > >+ */
>> >
>> > Could this be shorter?
>>
>> Yes. The comment in hazptr_torture_cleanup() already says why, so this
>> one can just point there:
>>
>> /* Keep going until hazptr_torture_cleanup() stops us, see there. */
>>
>> [...]
>
>The longer one is better.
>
>> > >+ /* The readers have stopped, so nothing new can be deferred. */
>> > >+ for_each_possible_cpu(cpu)
>> >
>> > Is the comment needed? I don't know if it's nessesary.
>>
>> I'd keep it. A reader can defer after the last pass in the loop, and
>> kthread_stop() can then end the loop without another pass, so this
>> pass is needed; the comment says why one pass is enough.
>>
>> > >+ /*
>> > >+ * Stop do_pending only after the writer and the readers: the writer
>> > >+ * may be waiting on hazard pointers that readers deferred.
>> > >+ */
>> >
>> > May we shorten this? Feel free to bikeshed that one.
>>
>> Sure:
>>
>> /* The writer may wait on hazard pointers that readers deferred. */
>
>And same here.
>
>I am sure that it is possible to create shorter versions that keep all
>to the information, but I am OK with Andrea's original versions.
>
>Bradley, Andrea is not a native English speaker and I believe that
>you are, so if you want better wording here, please provide it to him.
>Perhaps someday he will return the favor should you ever be required to
>write in Italian (or German or Ladin, for that matter). ;-)
Well, or he could be my language teacher :)
Yeah, if those don't need to be accounted for, I'm fine with this :D
Acked-by: Bradley Morgan <brads@mainlining.org>
>
> Thanx, Paul
>
>> Thanks for the review,
>> Andrea
--- Thanks!
https://lore.kernel.org/all/EE579805-42F2-4C58-B752-F28779EEB717@grrlz.net/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping
2026-10-19 16:20 [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping Andrea Parri
2026-10-19 16:22 ` Bradley Morgan
@ 2026-10-20 18:49 ` Paul E. McKenney
2026-10-21 9:06 ` Andrea Parri
1 sibling, 1 reply; 7+ messages in thread
From: Paul E. McKenney @ 2026-10-20 18:49 UTC (permalink / raw)
To: Andrea Parri
Cc: Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Josh Triplett, Boqun Feng, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Bradley Morgan,
Kunwu Chan, rcu, linux-kernel
On Mon, Oct 19, 2026 at 06:20:03PM +0200, Andrea Parri wrote:
> hazptrtorture can hang at shutdown when deferral is enabled, as in the
> PREEMPT scenario: the writer stays in ->sync() and kthread_stop() on it
> never returns, until kvm.sh kills QEMU:
>
> [ 1800.899278] hazptr-torture: Stopping hazptr_torture_do_pending task
> [ 1800.899447] hazptr-torture: Stopping hazptr_torture_writer task
> [ 1812.713870] hazptr-torture: rtc: 00000000225df70a ver: 12436 HTWS_SYNC tfle: 0 rta: 12437 rtaf: 0 rtf: 12427 onoff: 48783/48783:48786/48786 3,254:3,280 611671:731494 (HZ=1000) acq: 5720353149 rel: 5720210186 acqirq: 571927 relirq: 714778 reldefer: 714139 relundefer 714114
> [ 1812.713971] hazptr-torture: hazptr_torture_stats is stopping
>
> Summary: Potential hang (QEMU killed)
> !!! PID 1393523 hung at 1980 vs. 1800 seconds
>
> hazptr_torture_cleanup() stops the do_pending kthread before the writer
> and the readers. Once torture_must_stop(), do_pending makes one last
> pass and leaves its loop, but unless stutter_will_wait(), that pass
> releases the deferred hazard pointers of a single CPU.
>
> Readers can also still defer after that pass, from the iteration they
> are in when torture_must_stop() becomes true. Stopped readers hold no
> hazard pointer, so the writer waits on one of the 25 deferred hazard
> pointers above (reldefer - relundefer) that nothing releases.
>
> Keep do_pending running until hazptr_torture_cleanup() stops it, after
> the writer and the readers, releasing the deferred hazard pointers of
> all CPUs on each pass once torture_must_stop() and once more on exit.
> It now also sleeps between those passes, and kthread_stop() wakes it.
>
> This should be safe because readers defer only from their own loop,
> which they have left once torture_stop_kthread() returns for them, and
> the hazptr_torture_acquire() IPI runs synchronously within that loop.
>
> With this change, a 30-minute PREEMPT run on x86_64 with 8 CPUs ends
> with "End of test: SUCCESS" and with as many hazard pointers released
> from the pending lists as were deferred (reldefer: 960658 relundefer
> 960658).
>
> Fixes: f23d7b47ced9 ("hazptrtorture: Add kthread to release deferred hazard pointers")
> Assisted-by: LLM
> Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
Thank you for digging into this! Some questions and comments interspersed
below.
Thanx, Paul
> ---
> kernel/rcu/hazptrtorture.c | 24 ++++++++++++++++++------
> 1 file changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/rcu/hazptrtorture.c b/kernel/rcu/hazptrtorture.c
> index 7c8b5899fb011..5153720074644 100644
> --- a/kernel/rcu/hazptrtorture.c
> +++ b/kernel/rcu/hazptrtorture.c
> @@ -547,18 +547,25 @@ static int hazptr_torture_do_pending(void *arg)
> DEFINE_TORTURE_RANDOM(rand);
>
> VERBOSE_TOROUT_STRING("hazptr_torture_do_pending task started");
> - do {
> - if (stutter_will_wait()) {
> + /*
> + * Run until hazptr_torture_cleanup() stops this kthread, not just
> + * until torture_must_stop(): the writer can be waiting in ->sync()
> + * for a deferred hazard pointer while it is being stopped.
> + */
> + while (!kthread_should_stop()) {
> + if (torture_must_stop() || stutter_will_wait()) {
> for_each_possible_cpu(cpu)
> hazptr_torture_do_one_pending(cpu, &rand);
> } else {
> cpu = cpumask_next_wrap(cpu, cpu_possible_mask);
> hazptr_torture_do_one_pending(cpu, &rand);
> }
> - if (!torture_must_stop())
> - torture_hrtimeout_ms(kthread_do_pending_ms, USEC_PER_MSEC, &rand);
> + torture_hrtimeout_ms(kthread_do_pending_ms, USEC_PER_MSEC, &rand);
Is the theory here that a kthread_stop() will wake up this sleep anyway?
And if so, would that work if the kthread_stop() already happened?
(I do recall adding the torture_must_stop() checks due to delays at
kthread_stop() time, but perhaps things have changed since then.)
> // Omit stutter_wait() because this function needs to do cleanup.
> - } while (!torture_must_stop());
> + }
> + /* The readers have stopped, so nothing new can be deferred. */
> + for_each_possible_cpu(cpu)
> + hazptr_torture_do_one_pending(cpu, &rand);
Very good!
But given these two lines, do we need the changes to the loop?
> torture_kthread_stopping("hazptr_torture_do_pending");
> return 0;
> }
> @@ -773,7 +780,6 @@ hazptr_torture_cleanup(void)
> return;
> }
>
> - torture_stop_kthread(hazptr_torture_do_pending, do_pending_task);
> torture_stop_kthread(hazptr_torture_preempt, preempt_task);
> torture_stop_kthread(hazptr_torture_writer, writer_task);
>
> @@ -785,6 +791,12 @@ hazptr_torture_cleanup(void)
> reader_tasks = NULL;
> }
>
> + /*
> + * Stop do_pending only after the writer and the readers: the writer
> + * may be waiting on hazard pointers that readers deferred.
> + */
> + torture_stop_kthread(hazptr_torture_do_pending, do_pending_task);
> +
And this change looks good.
> torture_stop_kthread(hazptr_torture_stats, stats_task);
>
> /* Do torture-type-specific cleanup operations. */
>
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping
2026-10-20 18:49 ` Paul E. McKenney
@ 2026-10-21 9:06 ` Andrea Parri
0 siblings, 0 replies; 7+ messages in thread
From: Andrea Parri @ 2026-10-21 9:06 UTC (permalink / raw)
To: Paul E. McKenney
Cc: Andrea Parri, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Bradley Morgan, Kunwu Chan, rcu, linux-kernel
On Tue, Oct 20, 2026 at 11:49:08AM -0700, Paul E. McKenney wrote:
> On Mon, Oct 19, 2026 at 06:20:03PM +0200, Andrea Parri wrote:
[...]
> > - if (!torture_must_stop())
> > - torture_hrtimeout_ms(kthread_do_pending_ms, USEC_PER_MSEC, &rand);
> > + torture_hrtimeout_ms(kthread_do_pending_ms, USEC_PER_MSEC, &rand);
>
> Is the theory here that a kthread_stop() will wake up this sleep anyway?
> And if so, would that work if the kthread_stop() already happened?
>
> (I do recall adding the torture_must_stop() checks due to delays at
> kthread_stop() time, but perhaps things have changed since then.)
Yes, that is the theory. torture_hrtimeout_ns() does
set_current_state(TASK_IDLE) and then schedule_hrtimeout(), and
kthread_stop() sets KTHREAD_SHOULD_STOP before wake_up_process(),
which wakes TASK_IDLE sleepers. So:
- If kthread_stop() comes while do_pending sleeps, or between its
set_current_state() and schedule(), the sleep ends right away.
- If kthread_stop() has already happened, i.e., it comes between
the kthread_should_stop() check and set_current_state(), the
wakeup is lost, but KTHREAD_SHOULD_STOP stays set: do_pending
sleeps for one full period and the loop then exits. That is
kthread_do_pending_ms plus up to 1ms of fuzz, so 3-4ms by
default.
For comparison, without this patch do_pending leaves its loop at
torture_must_stop() and waits in torture_kthread_stopping(), which
sleeps in TASK_UNINTERRUPTIBLE for HZ/20 at a time, so it has the
same lost-wakeup window with a 50ms bound instead.
The next version says this in the changelog, which in the RFC only
says "kthread_stop() wakes it".
> > // Omit stutter_wait() because this function needs to do cleanup.
> > - } while (!torture_must_stop());
> > + }
> > + /* The readers have stopped, so nothing new can be deferred. */
> > + for_each_possible_cpu(cpu)
> > + hazptr_torture_do_one_pending(cpu, &rand);
>
> Very good!
>
> But given these two lines, do we need the changes to the loop?
I believe so, at least for the loop condition. The readers are
stopped after the writer, so during the writer's kthread_stop(), the
writer can be in ->sync() on a hazard pointer that a still-running
reader deferred, possibly from the iteration it was in when
torture_must_stop() became true. If the loop still ended at
torture_must_stop(), do_pending would make that final pass right away
and then wait in torture_kthread_stopping(), so a hazard pointer
deferred after that pass would leave the writer in ->sync(), as in the
hang above.
The other two loop changes follow from that one: the unconditional
sleep keeps do_pending from spinning while the writer and the readers
are being stopped, and the all-CPU pass once torture_must_stop() only
bounds the writer's wait to one period, instead of up to nr_cpu_ids
periods. I'm happy to drop the latter if you prefer the simpler loop.
> > + /*
> > + * Stop do_pending only after the writer and the readers: the writer
> > + * may be waiting on hazard pointers that readers deferred.
> > + */
> > + torture_stop_kthread(hazptr_torture_do_pending, do_pending_task);
> > +
>
> And this change looks good.
Thanks. In the next version, I'll keep the original (longer) comments
as you suggested in the other subthread, and post this patch in one
series with two patches that make hazptrtorture catch the slot-owner
race, as you asked in the slot-owner thread.
Thanks,
Andrea
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-21 9:07 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-19 16:20 [PATCH RFC -rcu/dev] hazptrtorture: Release all deferred hazard pointers before stopping Andrea Parri
2026-10-19 16:22 ` Bradley Morgan
2026-10-19 17:32 ` Andrea Parri
2026-10-20 18:36 ` Paul E. McKenney
2026-10-20 18:40 ` Bradley Morgan
2026-10-20 18:49 ` Paul E. McKenney
2026-10-21 9:06 ` Andrea Parri
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®