* [PATCH] rcutorture: Use __set_current_state() set task state in rcu_nocb_toggle()
@ 2026-07-02 10:11 Zqiang
2026-07-06 18:48 ` Paul E. McKenney
0 siblings, 1 reply; 6+ messages in thread
From: Zqiang @ 2026-07-02 10:11 UTC (permalink / raw)
To: paulmck, frederic, neeraj.upadhyay, joelagnelf, urezki, boqun
Cc: qiang.zhang, rcu, linux-kernel
In the rcu_nocb_toggle(), the schedule_hrtimeout() is called after the
state assignment with no condition check. the release-acquire pair from
raw_spin_unlock/lock(&cpu_base->lock), guarantee that task->__state is
visible to the hrtimer callback:
CPU0 CPU1
__set_current_state(TASK_INTERRUPTIBLE)
->WRITE_ONCE(task->__state, TASK_INTERRUPTIBLE)
schedule_hrtimeout
->hrtimer_sleeper_start_expires()
->raw_spin_lock_irqsave(&cpu_base->lock)
....
->raw_spin_unlock_irqrestore(&cpu_base->lock)
hard-irq:
raw_spin_lock_irqsave(&cpu_base->lock)
__hrtimer_run_queues
->__run_hrtimer
->raw_spin_unlock_irqrestore(&cpu_base->lock)
->fn(timer)
->hrtimer_wakeup
->wake_up_process
->try_to_wake_up
->READ task->__state
This commit therefore use the __set_current_state() to replace the
set_current_state() in rcu_nocb_toggle().
Signed-off-by: Zqiang <qiang.zhang@linux.dev>
---
kernel/rcu/rcutorture.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index b1bab59efde5..a0e6901e0f90 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -2947,7 +2947,7 @@ static int rcu_nocb_toggle(void *arg)
atomic_long_inc(&n_nocb_deoffload);
}
toggle_delay = torture_random(&rand) % toggle_fuzz + toggle_interval;
- set_current_state(TASK_INTERRUPTIBLE);
+ __set_current_state(TASK_INTERRUPTIBLE);
schedule_hrtimeout(&toggle_delay, HRTIMER_MODE_REL);
if (stutter_wait("rcu_nocb_toggle"))
sched_set_normal(current, oldnice);
--
2.17.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH] rcutorture: Use __set_current_state() set task state in rcu_nocb_toggle() 2026-07-02 10:11 [PATCH] rcutorture: Use __set_current_state() set task state in rcu_nocb_toggle() Zqiang @ 2026-07-06 18:48 ` Paul E. McKenney 2026-07-07 13:15 ` Zqiang 2026-07-07 15:36 ` Alan Huang 0 siblings, 2 replies; 6+ messages in thread From: Paul E. McKenney @ 2026-07-06 18:48 UTC (permalink / raw) To: Zqiang Cc: frederic, neeraj.upadhyay, joelagnelf, urezki, boqun, rcu, linux-kernel On Thu, Jul 02, 2026 at 06:11:25PM +0800, Zqiang wrote: > In the rcu_nocb_toggle(), the schedule_hrtimeout() is called after the > state assignment with no condition check. the release-acquire pair from > raw_spin_unlock/lock(&cpu_base->lock), guarantee that task->__state is > visible to the hrtimer callback: > > CPU0 CPU1 > __set_current_state(TASK_INTERRUPTIBLE) > ->WRITE_ONCE(task->__state, TASK_INTERRUPTIBLE) > schedule_hrtimeout > ->hrtimer_sleeper_start_expires() > ->raw_spin_lock_irqsave(&cpu_base->lock) > .... > ->raw_spin_unlock_irqrestore(&cpu_base->lock) > > hard-irq: > raw_spin_lock_irqsave(&cpu_base->lock) > __hrtimer_run_queues > ->__run_hrtimer > ->raw_spin_unlock_irqrestore(&cpu_base->lock) > ->fn(timer) > ->hrtimer_wakeup > ->wake_up_process > ->try_to_wake_up > ->READ task->__state > > This commit therefore use the __set_current_state() to replace the > set_current_state() in rcu_nocb_toggle(). > > Signed-off-by: Zqiang <qiang.zhang@linux.dev> This looks correct, and either drops an smp_mb() or converts an xchg() to a WRITE_ONCE(), which does decrease overhead. Except that rcu_nocb_toggle() is invoked very infrequently and has high overhead that I would expect to lose this overhead decrease in the noise. And it forces those reading the code to go figure out what is different between set_current_state() and __set_current_state(). So I am not convinced to take this patch. But am I missing something here? Thanx, Paul > --- > kernel/rcu/rcutorture.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c > index b1bab59efde5..a0e6901e0f90 100644 > --- a/kernel/rcu/rcutorture.c > +++ b/kernel/rcu/rcutorture.c > @@ -2947,7 +2947,7 @@ static int rcu_nocb_toggle(void *arg) > atomic_long_inc(&n_nocb_deoffload); > } > toggle_delay = torture_random(&rand) % toggle_fuzz + toggle_interval; > - set_current_state(TASK_INTERRUPTIBLE); > + __set_current_state(TASK_INTERRUPTIBLE); > schedule_hrtimeout(&toggle_delay, HRTIMER_MODE_REL); > if (stutter_wait("rcu_nocb_toggle")) > sched_set_normal(current, oldnice); > -- > 2.17.1 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rcutorture: Use __set_current_state() set task state in rcu_nocb_toggle() 2026-07-06 18:48 ` Paul E. McKenney @ 2026-07-07 13:15 ` Zqiang 2026-07-07 16:44 ` Paul E. McKenney 2026-07-07 15:36 ` Alan Huang 1 sibling, 1 reply; 6+ messages in thread From: Zqiang @ 2026-07-07 13:15 UTC (permalink / raw) To: paulmck Cc: frederic, neeraj.upadhyay, joelagnelf, urezki, boqun, rcu, linux-kernel > > On Thu, Jul 02, 2026 at 06:11:25PM +0800, Zqiang wrote: > > > > > In the rcu_nocb_toggle(), the schedule_hrtimeout() is called after the > > state assignment with no condition check. the release-acquire pair from > > raw_spin_unlock/lock(&cpu_base->lock), guarantee that task->__state is > > visible to the hrtimer callback: > > > > CPU0 CPU1 > > __set_current_state(TASK_INTERRUPTIBLE) > > ->WRITE_ONCE(task->__state, TASK_INTERRUPTIBLE) > > schedule_hrtimeout > > ->hrtimer_sleeper_start_expires() > > ->raw_spin_lock_irqsave(&cpu_base->lock) > > .... > > ->raw_spin_unlock_irqrestore(&cpu_base->lock) > > > > hard-irq: > > raw_spin_lock_irqsave(&cpu_base->lock) > > __hrtimer_run_queues > > ->__run_hrtimer > > ->raw_spin_unlock_irqrestore(&cpu_base->lock) > > ->fn(timer) > > ->hrtimer_wakeup > > ->wake_up_process > > ->try_to_wake_up > > ->READ task->__state > > > > This commit therefore use the __set_current_state() to replace the > > set_current_state() in rcu_nocb_toggle(). > > > > Signed-off-by: Zqiang <qiang.zhang@linux.dev> > > > This looks correct, and either drops an smp_mb() or converts an > xchg() to a WRITE_ONCE(), which does decrease overhead. Except that > rcu_nocb_toggle() is invoked very infrequently and has high overhead > that I would expect to lose this overhead decrease in the noise. And it > forces those reading the code to go figure out what is different between > set_current_state() and __set_current_state(). > > So I am not convinced to take this patch. But am I missing something here? Nothing was missed, only from memory ordering perspective, using set_current_state() is unnecessary. furthermore, in RCU tasks, we used the following code: __set_current_state(TASK_IDLE); // in this we use __set_current_state() schedule_hrtimeout_range(&exp, jiffies_to_nsecs(HZ / 2), HRTIMER_MODE_REL_HARD); Or perhaps we could also add a comment something like this(kernel/time/sleep_timeout.c): /* * __set_current_state() can be used in schedule_timeout_*() functions, because * schedule_timeout() calls schedule() unconditionally. */ Thanks Zqiang > > Thanx, Paul > > > > > --- > > kernel/rcu/rcutorture.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c > > index b1bab59efde5..a0e6901e0f90 100644 > > --- a/kernel/rcu/rcutorture.c > > +++ b/kernel/rcu/rcutorture.c > > @@ -2947,7 +2947,7 @@ static int rcu_nocb_toggle(void *arg) > > atomic_long_inc(&n_nocb_deoffload); > > } > > toggle_delay = torture_random(&rand) % toggle_fuzz + toggle_interval; > > - set_current_state(TASK_INTERRUPTIBLE); > > + __set_current_state(TASK_INTERRUPTIBLE); > > schedule_hrtimeout(&toggle_delay, HRTIMER_MODE_REL); > > if (stutter_wait("rcu_nocb_toggle")) > > sched_set_normal(current, oldnice); > > -- > > 2.17.1 > > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rcutorture: Use __set_current_state() set task state in rcu_nocb_toggle() 2026-07-07 13:15 ` Zqiang @ 2026-07-07 16:44 ` Paul E. McKenney 2026-07-09 12:05 ` Zqiang 0 siblings, 1 reply; 6+ messages in thread From: Paul E. McKenney @ 2026-07-07 16:44 UTC (permalink / raw) To: Zqiang Cc: frederic, neeraj.upadhyay, joelagnelf, urezki, boqun, rcu, linux-kernel On Tue, Jul 07, 2026 at 01:15:10PM +0000, Zqiang wrote: > > > > On Thu, Jul 02, 2026 at 06:11:25PM +0800, Zqiang wrote: > > > > > > > > In the rcu_nocb_toggle(), the schedule_hrtimeout() is called after the > > > state assignment with no condition check. the release-acquire pair from > > > raw_spin_unlock/lock(&cpu_base->lock), guarantee that task->__state is > > > visible to the hrtimer callback: > > > > > > CPU0 CPU1 > > > __set_current_state(TASK_INTERRUPTIBLE) > > > ->WRITE_ONCE(task->__state, TASK_INTERRUPTIBLE) > > > schedule_hrtimeout > > > ->hrtimer_sleeper_start_expires() > > > ->raw_spin_lock_irqsave(&cpu_base->lock) > > > .... > > > ->raw_spin_unlock_irqrestore(&cpu_base->lock) > > > > > > hard-irq: > > > raw_spin_lock_irqsave(&cpu_base->lock) > > > __hrtimer_run_queues > > > ->__run_hrtimer > > > ->raw_spin_unlock_irqrestore(&cpu_base->lock) > > > ->fn(timer) > > > ->hrtimer_wakeup > > > ->wake_up_process > > > ->try_to_wake_up > > > ->READ task->__state > > > > > > This commit therefore use the __set_current_state() to replace the > > > set_current_state() in rcu_nocb_toggle(). > > > > > > Signed-off-by: Zqiang <qiang.zhang@linux.dev> > > > > > This looks correct, and either drops an smp_mb() or converts an > > xchg() to a WRITE_ONCE(), which does decrease overhead. Except that > > rcu_nocb_toggle() is invoked very infrequently and has high overhead > > that I would expect to lose this overhead decrease in the noise. And it > > forces those reading the code to go figure out what is different between > > set_current_state() and __set_current_state(). > > > > So I am not convinced to take this patch. But am I missing something here? > > Nothing was missed, only from memory ordering perspective, > using set_current_state() is unnecessary. > furthermore, in RCU tasks, we used the following code: > > __set_current_state(TASK_IDLE); // in this we use __set_current_state() > schedule_hrtimeout_range(&exp, jiffies_to_nsecs(HZ / 2), HRTIMER_MODE_REL_HARD); > > Or perhaps we could also add a comment something like this(kernel/time/sleep_timeout.c): > > /* > * __set_current_state() can be used in schedule_timeout_*() functions, because > * schedule_timeout() calls schedule() unconditionally. > */ Would it make sense for a variant of schedule_hrtimeout_range() to take an TASK_* argument and then use __set_current_state() internally? That would get you the performance increase across all calls, but avoid bothering the typical user with the difference between __set_current_state() vs. set_current_state(). Thanx, Paul > Thanks > Zqiang > > > > > > Thanx, Paul > > > > > > > > --- > > > kernel/rcu/rcutorture.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c > > > index b1bab59efde5..a0e6901e0f90 100644 > > > --- a/kernel/rcu/rcutorture.c > > > +++ b/kernel/rcu/rcutorture.c > > > @@ -2947,7 +2947,7 @@ static int rcu_nocb_toggle(void *arg) > > > atomic_long_inc(&n_nocb_deoffload); > > > } > > > toggle_delay = torture_random(&rand) % toggle_fuzz + toggle_interval; > > > - set_current_state(TASK_INTERRUPTIBLE); > > > + __set_current_state(TASK_INTERRUPTIBLE); > > > schedule_hrtimeout(&toggle_delay, HRTIMER_MODE_REL); > > > if (stutter_wait("rcu_nocb_toggle")) > > > sched_set_normal(current, oldnice); > > > -- > > > 2.17.1 > > > > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rcutorture: Use __set_current_state() set task state in rcu_nocb_toggle() 2026-07-07 16:44 ` Paul E. McKenney @ 2026-07-09 12:05 ` Zqiang 0 siblings, 0 replies; 6+ messages in thread From: Zqiang @ 2026-07-09 12:05 UTC (permalink / raw) To: paulmck Cc: frederic, neeraj.upadhyay, joelagnelf, urezki, boqun, rcu, linux-kernel > > On Tue, Jul 07, 2026 at 01:15:10PM +0000, Zqiang wrote: > > > > > On Thu, Jul 02, 2026 at 06:11:25PM +0800, Zqiang wrote: > > > > > > > > In the rcu_nocb_toggle(), the schedule_hrtimeout() is called after the > > > state assignment with no condition check. the release-acquire pair from > > > raw_spin_unlock/lock(&cpu_base->lock), guarantee that task->__state is > > > visible to the hrtimer callback: > > > > > > CPU0 CPU1 > > > __set_current_state(TASK_INTERRUPTIBLE) > > > ->WRITE_ONCE(task->__state, TASK_INTERRUPTIBLE) > > > schedule_hrtimeout > > > ->hrtimer_sleeper_start_expires() > > > ->raw_spin_lock_irqsave(&cpu_base->lock) > > > .... > > > ->raw_spin_unlock_irqrestore(&cpu_base->lock) > > > > > > hard-irq: > > > raw_spin_lock_irqsave(&cpu_base->lock) > > > __hrtimer_run_queues > > > ->__run_hrtimer > > > ->raw_spin_unlock_irqrestore(&cpu_base->lock) > > > ->fn(timer) > > > ->hrtimer_wakeup > > > ->wake_up_process > > > ->try_to_wake_up > > > ->READ task->__state > > > > > > This commit therefore use the __set_current_state() to replace the > > > set_current_state() in rcu_nocb_toggle(). > > > > > > Signed-off-by: Zqiang <qiang.zhang@linux.dev> > > > > > This looks correct, and either drops an smp_mb() or converts an > > xchg() to a WRITE_ONCE(), which does decrease overhead. Except that > > rcu_nocb_toggle() is invoked very infrequently and has high overhead > > that I would expect to lose this overhead decrease in the noise. And it > > forces those reading the code to go figure out what is different between > > set_current_state() and __set_current_state(). > > > > So I am not convinced to take this patch. But am I missing something here? > > > > Nothing was missed, only from memory ordering perspective, > > using set_current_state() is unnecessary. > > furthermore, in RCU tasks, we used the following code: > > > > __set_current_state(TASK_IDLE); // in this we use __set_current_state() > > schedule_hrtimeout_range(&exp, jiffies_to_nsecs(HZ / 2), HRTIMER_MODE_REL_HARD); > > > > Or perhaps we could also add a comment something like this(kernel/time/sleep_timeout.c): > > > > /* > > * __set_current_state() can be used in schedule_timeout_*() functions, because > > * schedule_timeout() calls schedule() unconditionally. > > */ > > > Would it make sense for a variant of schedule_hrtimeout_range() to take an > TASK_* argument and then use __set_current_state() internally? That would > get you the performance increase across all calls, but avoid bothering > the typical user with the difference between __set_current_state() vs. > set_current_state(). This is a good idea. Thanks Zqiang > > Thanx, Paul > > > > > Thanks > > Zqiang > > > > > > > > Thanx, Paul > > > > > > > > --- > > > kernel/rcu/rcutorture.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c > > > index b1bab59efde5..a0e6901e0f90 100644 > > > --- a/kernel/rcu/rcutorture.c > > > +++ b/kernel/rcu/rcutorture.c > > > @@ -2947,7 +2947,7 @@ static int rcu_nocb_toggle(void *arg) > > > atomic_long_inc(&n_nocb_deoffload); > > > } > > > toggle_delay = torture_random(&rand) % toggle_fuzz + toggle_interval; > > > - set_current_state(TASK_INTERRUPTIBLE); > > > + __set_current_state(TASK_INTERRUPTIBLE); > > > schedule_hrtimeout(&toggle_delay, HRTIMER_MODE_REL); > > > if (stutter_wait("rcu_nocb_toggle")) > > > sched_set_normal(current, oldnice); > > > -- > > > 2.17.1 > > > > > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rcutorture: Use __set_current_state() set task state in rcu_nocb_toggle() 2026-07-06 18:48 ` Paul E. McKenney 2026-07-07 13:15 ` Zqiang @ 2026-07-07 15:36 ` Alan Huang 1 sibling, 0 replies; 6+ messages in thread From: Alan Huang @ 2026-07-07 15:36 UTC (permalink / raw) To: paulmck Cc: Zqiang, frederic, neeraj.upadhyay, joelagnelf, urezki, boqun, rcu, linux-kernel On Jul 7, 2026, at 02:48, Paul E. McKenney <paulmck@kernel.org> wrote: > > On Thu, Jul 02, 2026 at 06:11:25PM +0800, Zqiang wrote: >> In the rcu_nocb_toggle(), the schedule_hrtimeout() is called after the >> state assignment with no condition check. the release-acquire pair from >> raw_spin_unlock/lock(&cpu_base->lock), guarantee that task->__state is >> visible to the hrtimer callback: >> >> CPU0 CPU1 >> __set_current_state(TASK_INTERRUPTIBLE) >> ->WRITE_ONCE(task->__state, TASK_INTERRUPTIBLE) >> schedule_hrtimeout >> ->hrtimer_sleeper_start_expires() >> ->raw_spin_lock_irqsave(&cpu_base->lock) >> .... >> ->raw_spin_unlock_irqrestore(&cpu_base->lock) >> >> hard-irq: >> raw_spin_lock_irqsave(&cpu_base->lock) >> __hrtimer_run_queues >> ->__run_hrtimer >> ->raw_spin_unlock_irqrestore(&cpu_base->lock) >> ->fn(timer) >> ->hrtimer_wakeup >> ->wake_up_process >> ->try_to_wake_up >> ->READ task->__state >> >> This commit therefore use the __set_current_state() to replace the >> set_current_state() in rcu_nocb_toggle(). >> >> Signed-off-by: Zqiang <qiang.zhang@linux.dev> > > This looks correct, and either drops an smp_mb() or converts an > xchg() to a WRITE_ONCE(), which does decrease overhead. Except that > rcu_nocb_toggle() is invoked very infrequently and has high overhead > that I would expect to lose this overhead decrease in the noise. And it > forces those reading the code to go figure out what is different between Agreed. I did end up reading the code. > set_current_state() and __set_current_state(). > > So I am not convinced to take this patch. But am I missing something here? > > Thanx, Paul > >> --- >> kernel/rcu/rcutorture.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c >> index b1bab59efde5..a0e6901e0f90 100644 >> --- a/kernel/rcu/rcutorture.c >> +++ b/kernel/rcu/rcutorture.c >> @@ -2947,7 +2947,7 @@ static int rcu_nocb_toggle(void *arg) >> atomic_long_inc(&n_nocb_deoffload); >> } >> toggle_delay = torture_random(&rand) % toggle_fuzz + toggle_interval; >> - set_current_state(TASK_INTERRUPTIBLE); >> + __set_current_state(TASK_INTERRUPTIBLE); >> schedule_hrtimeout(&toggle_delay, HRTIMER_MODE_REL); >> if (stutter_wait("rcu_nocb_toggle")) >> sched_set_normal(current, oldnice); >> -- >> 2.17.1 >> > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-09 12:05 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-02 10:11 [PATCH] rcutorture: Use __set_current_state() set task state in rcu_nocb_toggle() Zqiang 2026-07-06 18:48 ` Paul E. McKenney 2026-07-07 13:15 ` Zqiang 2026-07-07 16:44 ` Paul E. McKenney 2026-07-09 12:05 ` Zqiang 2026-07-07 15:36 ` Alan Huang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox