From: Uladzislau Rezki <urezki@gmail.com>
To: Z qiang <qiang.zhang1211@gmail.com>,
"Paul E . McKenney" <paulmck@kernel.org>
Cc: "Paul E . McKenney" <paulmck@kernel.org>,
qiang.zhang@linux.dev, Joel Fernandes <joelagnelf@nvidia.com>,
"Uladzislau Rezki (Sony)" <urezki@gmail.com>,
Frederic Weisbecker <frederic@kernel.org>,
Boqun Feng <boqun.feng@gmail.com>, RCU <rcu@vger.kernel.org>,
LKML <linux-kernel@vger.kernel.org>,
Saravana Kannan <saravanak@kernel.org>
Subject: Re: [PATCH -next v1 01/12] rcutorture: Fully test lazy RCU
Date: Sun, 17 May 2026 14:40:42 +0200 [thread overview]
Message-ID: <agm3SuhBoVjkunjG@pc636> (raw)
In-Reply-To: <CALm+0cVY4izVdUDVdqVCfGgREMbHcyeDryYwYp_gsHevt4t8_w@mail.gmail.com>
On Thu, May 14, 2026 at 09:33:10PM +0800, Z qiang wrote:
> >
> > From: "Paul E. McKenney" <paulmck@kernel.org>
> >
> > Currently, rcutorture bypasses lazy RCU by using call_rcu_hurry().
> > This works, avoiding the dreaded rtort_pipe_count WARN(), but fails to
> > fully test lazy RCU. The rtort_pipe_count WARN() splats because lazy RCU
> > could delay the start of an RCU grace period for a full stutter period,
> > which defaults to only three seconds.
> >
> > This commit therefore reverts the call_rcu_hurry() instances
> > back to call_rcu(), but, in kernels built with CONFIG_RCU_LAZY=y,
> > queues a workqueue handler just before the call to stutter_wait() in
> > rcu_torture_writer(). This workqueue handler invokes rcu_barrier(),
> > which motivates any lingering lazy callbacks, thus avoiding the splat.
> >
> > Questions for review:
> >
> > 1. Should we avoid queueing work for RCU implementations not
> > supporting lazy callbacks?
>
> Hello, Paul
>
> maybe we can do this:
>
> rcu_ops = {
> ...
> .support_lazy = IS_ENABLED(CONFIG_RCU_LAZY),
> };
>
> and
>
> if (cur_ops->support_lazy )
> queue_work(..., &lazy_work);
>
> >
> > 2. Should we avoid queueing work in kernels built with
> > CONFIG_RCU_LAZY=y, but that were not booted with the
> > rcutree.enable_rcu_lazy kernel boot parameter set? (Note that
> > this requires some ugliness to access this parameter, and must
> > also handle Tiny RCU.)
> >
> > 3. Does the rcu_torture_ops structure need a ->call_hurry() field,
> > and if so, why? If not, why not?
> >
> > 4. Your additional questions here!
> >
> > Reported-by: Saravana Kannan <saravanak@kernel.org>
> > Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> > Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
> > ---
> > kernel/rcu/rcutorture.c | 21 ++++++++++++++++++---
> > 1 file changed, 18 insertions(+), 3 deletions(-)
> >
> > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> > index 5f2848b828dc..91ba3160ba6a 100644
> > --- a/kernel/rcu/rcutorture.c
> > +++ b/kernel/rcu/rcutorture.c
> > @@ -572,7 +572,7 @@ static unsigned long rcu_no_completed(void)
> >
> > static void rcu_torture_deferred_free(struct rcu_torture *p)
> > {
> > - call_rcu_hurry(&p->rtort_rcu, rcu_torture_cb);
> > + call_rcu(&p->rtort_rcu, rcu_torture_cb);
> > }
> >
> > static void rcu_sync_torture_init(void)
> > @@ -619,7 +619,7 @@ static struct rcu_torture_ops rcu_ops = {
> > .poll_gp_state_exp = poll_state_synchronize_rcu,
> > .cond_sync_exp = cond_synchronize_rcu_expedited,
> > .cond_sync_exp_full = cond_synchronize_rcu_expedited_full,
> > - .call = call_rcu_hurry,
> > + .call = call_rcu,
> > .cb_barrier = rcu_barrier,
> > .fqs = rcu_force_quiescent_state,
> > .gp_kthread_dbg = show_rcu_gp_kthreads,
> > @@ -1145,7 +1145,7 @@ static void rcu_tasks_torture_deferred_free(struct rcu_torture *p)
> >
> > static void synchronize_rcu_mult_test(void)
> > {
> > - synchronize_rcu_mult(call_rcu_tasks, call_rcu_hurry);
> > + synchronize_rcu_mult(call_rcu_tasks, call_rcu);
> > }
> >
> > static struct rcu_torture_ops tasks_ops = {
> > @@ -1631,6 +1631,17 @@ static void do_rtws_sync(struct torture_random_state *trsp, void (*sync)(void))
> > cpus_read_unlock();
> > }
> >
> > +/*
> > + * Do an rcu_barrier() to motivate lazy callbacks during a stutter
> > + * pause. Without this, we can get false-positives rtort_pipe_count
> > + * splats.
> > + */
> > +static void rcu_torture_writer_work(struct work_struct *work)
> > +{
> > + if (cur_ops->cb_barrier)
> > + cur_ops->cb_barrier();
> > +}
> > +
> > /*
> > * RCU torture writer kthread. Repeatedly substitutes a new structure
> > * for that pointed to by rcu_torture_current, freeing the old structure
> > @@ -1651,6 +1662,7 @@ rcu_torture_writer(void *arg)
> > int i;
> > int idx;
> > unsigned long j;
> > + struct work_struct lazy_work;
> > int oldnice = task_nice(current);
> > struct rcu_gp_oldstate *rgo = NULL;
> > int rgo_size = 0;
> > @@ -1667,6 +1679,7 @@ rcu_torture_writer(void *arg)
> > stallsdone += (stall_cpu_holdoff + stall_gp_kthread + stall_cpu + 60) *
> > HZ * (stall_cpu_repeat + 1);
> > VERBOSE_TOROUT_STRING("rcu_torture_writer task started");
> > + INIT_WORK_ONSTACK(&lazy_work, rcu_torture_writer_work);
> > if (!can_expedite)
> > pr_alert("%s" TORTURE_FLAG
> > " GP expediting controlled from boot/sysfs for %s.\n",
> > @@ -1895,6 +1908,8 @@ rcu_torture_writer(void *arg)
> > !rcu_gp_is_normal();
> > }
> > rcu_torture_writer_state = RTWS_STUTTER;
> > + if (IS_ENABLED(CONFIG_RCU_LAZY))
> > + queue_work(system_percpu_wq, &lazy_work);
>
>
> When the task ends, the lazy_work should be cancel and destroy:
>
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index f593f8b794dd..5adf537ab410 100644
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -1682,7 +1682,6 @@ rcu_torture_writer(void *arg)
> stallsdone += (stall_cpu_holdoff + stall_gp_kthread + stall_cpu + 60) *
> HZ * (stall_cpu_repeat + 1);
> VERBOSE_TOROUT_STRING("rcu_torture_writer task started");
> - INIT_WORK_ONSTACK(&lazy_work, rcu_torture_writer_work);
> if (!can_expedite)
> pr_alert("%s" TORTURE_FLAG
> " GP expediting controlled from boot/sysfs for %s.\n",
> @@ -1719,6 +1718,8 @@ rcu_torture_writer(void *arg)
> pr_alert("%s" TORTURE_FLAG " Waited %lu jiffies for boot to complete.\n",
> torture_type, jiffies - j);
>
> + INIT_WORK_ONSTACK(&lazy_work, rcu_torture_writer_work);
> +
> do {
> rcu_torture_writer_state = RTWS_FIXED_DELAY;
> torture_hrtimeout_us(500, 1000, &rand);
> @@ -1943,6 +1944,9 @@ rcu_torture_writer(void *arg)
> pr_alert("%s" TORTURE_FLAG
> " Dynamic grace-period expediting was disabled.\n",
> torture_type);
> + if (IS_ENABLED(CONFIG_RCU_LAZY))
> + cancel_work_sync(&lazy_work);
> + destroy_work_on_stack(&lazy_work);
> kfree(ulo);
> kfree(rgo);
> rcu_torture_writer_state = RTWS_STOPPING;
>
I agree, we seem miss destroying the work via destroy_work_on_stack()
and "sync" the lazy_work work via cancel_work_sync().
Paul, any thoughts?
--
Uladzislau Rezki
next prev parent reply other threads:[~2026-05-17 12:40 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-11 17:54 [PATCH -next v1 00/12] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 01/12] rcutorture: Fully test lazy RCU Uladzislau Rezki (Sony)
2026-05-14 13:33 ` Z qiang
2026-05-17 12:40 ` Uladzislau Rezki [this message]
2026-05-17 18:30 ` Paul E. McKenney
2026-05-18 15:36 ` Uladzislau Rezki
2026-05-19 0:38 ` Paul E. McKenney
2026-05-19 16:04 ` Uladzislau Rezki
2026-05-11 17:54 ` [PATCH -next v1 02/12] torture: Add torture_sched_set_normal() for user-specified nice values Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 03/12] torture: Improve kvm-series.sh header comment Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 04/12] torture: Allow "norm" abbreviation for "normal" Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 05/12] srcu: Don't queue workqueue handlers to never-online CPUs Uladzislau Rezki (Sony)
2026-05-13 10:38 ` Thorsten Leemhuis
2026-05-17 12:47 ` Uladzislau Rezki
2026-05-17 18:03 ` Paul E. McKenney
2026-05-17 19:11 ` Thorsten Leemhuis
2026-05-18 16:13 ` Boqun Feng
2026-05-18 17:05 ` Uladzislau Rezki
2026-05-18 19:30 ` Boqun Feng
2026-05-19 13:19 ` Uladzislau Rezki
2026-05-19 4:52 ` Jiri Slaby
2026-05-11 17:54 ` [PATCH -next v1 06/12] srcu: Fix kerneldoc header comment typo in srcu_down_read_fast() Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 07/12] checkpatch: Undeprecate rcu_read_lock_trace() and rcu_read_unlock_trace() Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 08/12] rcu: Simplify rcu_do_batch() by applying clamp() Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 09/12] rcu: Simplify param_set_next_fqs_jiffies() by applying clamp_val() Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 10/12] rcu: Document rcu_access_pointer() feeding into cmpxchg() Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 11/12] rcu: Latch normal synchronize_rcu() path on flood Uladzislau Rezki (Sony)
2026-05-11 17:54 ` [PATCH -next v1 12/12] rcu-tasks: Fix possible boot-time tests failed for the call_rcu_tasks() Uladzislau Rezki (Sony)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=agm3SuhBoVjkunjG@pc636 \
--to=urezki@gmail.com \
--cc=boqun.feng@gmail.com \
--cc=frederic@kernel.org \
--cc=joelagnelf@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=paulmck@kernel.org \
--cc=qiang.zhang1211@gmail.com \
--cc=qiang.zhang@linux.dev \
--cc=rcu@vger.kernel.org \
--cc=saravanak@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.