All of lore.kernel.org
 help / color / mirror / Atom feed
From: Uladzislau Rezki <urezki@gmail.com>
To: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Uladzislau Rezki <urezki@gmail.com>,
	Z qiang <qiang.zhang1211@gmail.com>,
	qiang.zhang@linux.dev, Joel Fernandes <joelagnelf@nvidia.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: Tue, 19 May 2026 18:04:56 +0200	[thread overview]
Message-ID: <agyKKNF52K6kq7Cs@milan> (raw)
In-Reply-To: <003e94b0-d562-4cc1-a0be-db68e1969229@paulmck-laptop>

On Mon, May 18, 2026 at 05:38:48PM -0700, Paul E. McKenney wrote:
> On Mon, May 18, 2026 at 05:36:08PM +0200, Uladzislau Rezki wrote:
> > On Sun, May 17, 2026 at 11:30:14AM -0700, Paul E. McKenney wrote:
> > > On Sun, May 17, 2026 at 02:40:42PM +0200, Uladzislau Rezki wrote:
> > > > 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?
> > > 
> > > Good eyes!!!  I will take a closer look tomorrow.
> > > 
> > > In the meantime, one question...  Do we want to test for your new
> > > ->support_lazy instead of IS_ENABLED(CONFIG_RCU_LAZY) for that
> > > cancel_work_sync() and destroy_work_on_stack()?  If we really need
> > > IS_ENABLED(CONFIG_RCU_LAZY), could you please suggest a comment giving
> > > the reasoning?
> > > 
> > To me IS_ENABLED(CONFIG_RCU_LAZY) is enough :) I am not sure we really
> > need ->support_lazy flag.
> 
> Good point, given that the queue_work() is also guarded by that same
> IS_ENABLED(CONFIG_RCU_LAZY).
> 
> How does the patch below, based on the patch I sent initially, look?
> 
> I can fold it in and resend, or you can do so, your choice.
> 
> 							Thanx, Paul
> 
> ------------------------------------------------------------------------
> 
> commit 68284a54b40f4fb1a6595fb9263aae47a56f20bb
> Author: Paul E. McKenney <paulmck@kernel.org>
> Date:   Mon May 18 17:36:10 2026 -0700
> 
>     squash! rcutorture: Fully test lazy RCU
>     
>     [ paulmck: Apply Z qiang feedback. ]
>     
>     Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> 
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index e1b4f4dbbb5819..878706beea01cd 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);
>  
> +	if (IS_ENABLED(CONFIG_RCU_LAZY))
> +		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,10 @@ 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 will fold it on my own, Paul!

--
Uladzislau Rezki

  reply	other threads:[~2026-05-19 16:05 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
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 [this message]
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=agyKKNF52K6kq7Cs@milan \
    --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.