All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window
@ 2026-05-19 19:45 Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 01/11] rcutorture: Fully test lazy RCU Uladzislau Rezki (Sony)
                   ` (10 more replies)
  0 siblings, 11 replies; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki

Hello!
 
The git tree with candidate patches for Linux-7.2, based on Linux 7.1-rc4
can be found at:
 
git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git
(tag: rcu-7.2-v2-20260519)

Please review and let me know if any patches should be updated.

Paul E. McKenney (9):
  rcutorture: Fully test lazy RCU
  torture: Add torture_sched_set_normal() for user-specified nice values
  torture: Improve kvm-series.sh header comment
  torture: Allow "norm" abbreviation for "normal"
  srcu: Fix kerneldoc header comment typo in srcu_down_read_fast()
  checkpatch: Undeprecate rcu_read_lock_trace() and
    rcu_read_unlock_trace()
  rcu: Simplify rcu_do_batch() by applying clamp()
  rcu: Simplify param_set_next_fqs_jiffies() by applying clamp_val()
  rcu: Document rcu_access_pointer() feeding into cmpxchg()

Uladzislau Rezki (Sony) (1):
  rcu: Latch normal synchronize_rcu() path on flood

Zqiang (1):
  rcu-tasks: Fix possible boot-time tests failed for the
    call_rcu_tasks()

 .../admin-guide/kernel-parameters.txt         | 10 ++--
 include/linux/rcupdate.h                      | 12 ++--
 include/linux/srcu.h                          |  2 +-
 include/linux/torture.h                       |  1 +
 kernel/rcu/rcutorture.c                       | 29 +++++++++-
 kernel/rcu/tasks.h                            |  3 +-
 kernel/rcu/tree.c                             | 56 ++++++++++++++-----
 kernel/torture.c                              | 16 ++++++
 scripts/checkpatch.pl                         |  5 +-
 .../selftests/rcutorture/bin/kvm-series.sh    | 11 ++--
 .../selftests/rcutorture/bin/torture.sh       |  2 +-
 11 files changed, 109 insertions(+), 38 deletions(-)

-- 
2.47.3


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH -next v2 01/11] rcutorture: Fully test lazy RCU
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 02/11] torture: Add torture_sched_set_normal() for user-specified nice values Uladzislau Rezki (Sony)
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki, Saravana Kannan

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.

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 | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 5f2848b828dc..882a158ada7b 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;
@@ -1703,6 +1715,9 @@ 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);
@@ -1895,6 +1910,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);
 		stutter_waited = stutter_wait("rcu_torture_writer");
 		if (stutter_waited &&
 		    !atomic_read(&rcu_fwd_cb_nodelay) &&
@@ -1925,6 +1942,12 @@ 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;
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 02/11] torture: Add torture_sched_set_normal() for user-specified nice values
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 01/11] rcutorture: Fully test lazy RCU Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 03/11] torture: Improve kvm-series.sh header comment Uladzislau Rezki (Sony)
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki

From: "Paul E. McKenney" <paulmck@kernel.org>

This new torture_sched_set_normal() function clamps the nice value at
the MIN_NICE..MAX_NICE limits, splatting it these limits are exceeded.
It then invokes sched_set_normal() to set the new value.  This prevents
more difficult-to-debug failures within the scheduler.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 include/linux/torture.h |  1 +
 kernel/torture.c        | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/linux/torture.h b/include/linux/torture.h
index 1b59056c3b18..c9b47d138302 100644
--- a/include/linux/torture.h
+++ b/include/linux/torture.h
@@ -129,6 +129,7 @@ void _torture_stop_kthread(char *m, struct task_struct **tp);
 #else
 #define torture_preempt_schedule()	do { } while (0)
 #endif
+void torture_sched_set_normal(struct task_struct *t, int nice);
 
 #if IS_ENABLED(CONFIG_RCU_TORTURE_TEST) || IS_MODULE(CONFIG_RCU_TORTURE_TEST) || IS_ENABLED(CONFIG_LOCK_TORTURE_TEST) || IS_MODULE(CONFIG_LOCK_TORTURE_TEST)
 long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn);
diff --git a/kernel/torture.c b/kernel/torture.c
index 62c1ac777694..77cb3589b19f 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -972,3 +972,19 @@ void _torture_stop_kthread(char *m, struct task_struct **tp)
 	*tp = NULL;
 }
 EXPORT_SYMBOL_GPL(_torture_stop_kthread);
+
+/*
+ * Set the specified task's niceness value, saturating at limits.
+ * Saturating noisily, but saturating.
+ */
+void torture_sched_set_normal(struct task_struct *t, int nice)
+{
+	int realnice = nice;
+
+	if (WARN_ON_ONCE(realnice > MAX_NICE))
+		realnice = MAX_NICE;
+	if (WARN_ON_ONCE(realnice < MIN_NICE))
+		realnice = MIN_NICE;
+	sched_set_normal(t, realnice);
+}
+EXPORT_SYMBOL_GPL(torture_sched_set_normal);
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 03/11] torture: Improve kvm-series.sh header comment
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 01/11] rcutorture: Fully test lazy RCU Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 02/11] torture: Add torture_sched_set_normal() for user-specified nice values Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 04/11] torture: Allow "norm" abbreviation for "normal" Uladzislau Rezki (Sony)
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki

From: "Paul E. McKenney" <paulmck@kernel.org>

The constraints on the arguments to kvm-series.sh are easy to forget,
so this commit adds examples in the header comment.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 tools/testing/selftests/rcutorture/bin/kvm-series.sh | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/rcutorture/bin/kvm-series.sh b/tools/testing/selftests/rcutorture/bin/kvm-series.sh
index c4ee5f910931..be9412538fb8 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-series.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-series.sh
@@ -1,12 +1,13 @@
 #!/bin/bash
 # SPDX-License-Identifier: GPL-2.0+
 #
-# Usage: kvm-series.sh config-list commit-id-list [ kvm.sh parameters ]
+# Usage: kvm-series.sh config-list commit-id-range [ kvm.sh parameters ]
 #
-# Tests the specified list of unadorned configs ("TREE01 SRCU-P" but not
-# "CFLIST" or "3*TRACE01") and an indication of a set of commits to test,
-# then runs each commit through the specified list of commits using kvm.sh.
-# The runs are grouped into a -series/config/commit directory tree.
+# Tests the specified list of unadorned configs ("TREE01 SRCU-P" but
+# not "CFLIST" or "3*TRACE01") and an indication of a range of commits
+# ("v7.0-rc1..rcu/dev", but not "cd0ce7bab0408 ff74db28df623 17c52d7b31a1f")
+# to test, then runs each commit through the specified list of commits using
+# kvm.sh.  The runs are grouped into a -series/config/commit directory tree.
 # Each run defaults to a duration of one minute.
 #
 # Run in top-level Linux source directory.  Please note that this is in
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 04/11] torture: Allow "norm" abbreviation for "normal"
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
                   ` (2 preceding siblings ...)
  2026-05-19 19:45 ` [PATCH -next v2 03/11] torture: Improve kvm-series.sh header comment Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 05/11] srcu: Fix kerneldoc header comment typo in srcu_down_read_fast() Uladzislau Rezki (Sony)
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki

From: "Paul E. McKenney" <paulmck@kernel.org>

This adds "--do-norm", --do-no-norm", and "--no-norm" synonyms for the
"--do-normal" group of torture.sh command-line arguments.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 tools/testing/selftests/rcutorture/bin/torture.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/rcutorture/bin/torture.sh b/tools/testing/selftests/rcutorture/bin/torture.sh
index a33ba109ef0b..f0083891ee81 100755
--- a/tools/testing/selftests/rcutorture/bin/torture.sh
+++ b/tools/testing/selftests/rcutorture/bin/torture.sh
@@ -184,7 +184,7 @@ do
 		do_clocksourcewd=no
 		do_srcu_lockdep=no
 		;;
-	--do-normal|--do-no-normal|--no-normal)
+	--do-normal|--do-norm|--do-no-normal|--do-no-norm|--no-normal|--no-norm)
 		do_normal=`doyesno "$1" --do-normal`
 		explicit_normal=yes
 		;;
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 05/11] srcu: Fix kerneldoc header comment typo in srcu_down_read_fast()
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
                   ` (3 preceding siblings ...)
  2026-05-19 19:45 ` [PATCH -next v2 04/11] torture: Allow "norm" abbreviation for "normal" Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 06/11] checkpatch: Undeprecate rcu_read_lock_trace() and rcu_read_unlock_trace() Uladzislau Rezki (Sony)
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki

From: "Paul E. McKenney" <paulmck@kernel.org>

s/srcu_read_lock_safe()/srcu_read_lock_fast_updown(), there being no
such thing as srcu_read_lock_safe().

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 include/linux/srcu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index 81b1938512d5..a54ce9e808b9 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -397,7 +397,7 @@ static inline struct srcu_ctr __percpu *srcu_read_lock_fast_notrace(struct srcu_
  *
  * The same srcu_struct may be used concurrently by srcu_down_read_fast()
  * and srcu_read_lock_fast().  However, the same definition/initialization
- * requirements called out for srcu_read_lock_safe() apply.
+ * requirements called out for srcu_read_lock_fast_updown() apply.
  */
 static inline struct srcu_ctr __percpu *srcu_down_read_fast(struct srcu_struct *ssp) __acquires_shared(ssp)
 {
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 06/11] checkpatch: Undeprecate rcu_read_lock_trace() and rcu_read_unlock_trace()
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
                   ` (4 preceding siblings ...)
  2026-05-19 19:45 ` [PATCH -next v2 05/11] srcu: Fix kerneldoc header comment typo in srcu_down_read_fast() Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 07/11] rcu: Simplify rcu_do_batch() by applying clamp() Uladzislau Rezki (Sony)
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki, Puranjay Mohan, Andy Whitcroft,
	Joe Perches, Dwaipayan Ray, Lukas Bulwahn

From: "Paul E. McKenney" <paulmck@kernel.org>

It turns out that there are BPF use cases that rely on nesting RCU
Tasks Trace readers.  These use cases are well-served by the old
rcu_read_lock_trace() and rcu_read_unlock_trace() functions that maintain
a nesting counter in the task_struct structure.  But these use cases incur
a performance penalty when using the shiny new rcu_read_lock_tasks_trace()
and rcu_read_unlock_tasks_trace() functions, which nest in the same way
that SRCU does.

This means that rcu_read_lock_trace() and rcu_read_unlock_trace()
will be with us for some time.  Therefore, remove the checkpatch.pl
deprecation.

Also, the rcu_read_lock_tasks_trace() and rcu_read_unlock_tasks_trace()
functions are intended for use only by BPF.  Therefore, add them to
the list of functions that checkpatch complains about outside of BPF
(and of course, RCU).

Reported-by: Puranjay Mohan <puranjay@kernel.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Andy Whitcroft <apw@canonical.com>
Cc: Joe Perches <joe@perches.com>
Cc: Dwaipayan Ray <dwaipayanray1@gmail.com>
Cc: Lukas Bulwahn <lukas.bulwahn@gmail.com>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 scripts/checkpatch.pl | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 0492d6afc9a1..cc5bbd70cb84 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -865,8 +865,6 @@ our %deprecated_apis = (
 	"DEFINE_IDR"				=> "DEFINE_XARRAY",
 	"idr_init"				=> "xa_init",
 	"idr_init_base"				=> "xa_init_flags",
-	"rcu_read_lock_trace"			=> "rcu_read_lock_tasks_trace",
-	"rcu_read_unlock_trace"			=> "rcu_read_unlock_tasks_trace",
 );
 
 #Create a search pattern for all these strings to speed up a loop below
@@ -7596,12 +7594,15 @@ sub process {
 
 # Complain about RCU Tasks Trace used outside of BPF (and of course, RCU).
 		our $rcu_trace_funcs = qr{(?x:
+			rcu_read_lock_tasks_trace |
 			rcu_read_lock_trace |
 			rcu_read_lock_trace_held |
 			rcu_read_unlock_trace |
+			rcu_read_unlock_tasks_trace |
 			call_rcu_tasks_trace |
 			synchronize_rcu_tasks_trace |
 			rcu_barrier_tasks_trace |
+			rcu_tasks_trace_expedite_current |
 			rcu_request_urgent_qs_task
 		)};
 		our $rcu_trace_paths = qr{(?x:
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 07/11] rcu: Simplify rcu_do_batch() by applying clamp()
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
                   ` (5 preceding siblings ...)
  2026-05-19 19:45 ` [PATCH -next v2 06/11] checkpatch: Undeprecate rcu_read_lock_trace() and rcu_read_unlock_trace() Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-20 12:26   ` Frederic Weisbecker
  2026-05-19 19:45 ` [PATCH -next v2 08/11] rcu: Simplify param_set_next_fqs_jiffies() by applying clamp_val() Uladzislau Rezki (Sony)
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki

From: "Paul E. McKenney" <paulmck@kernel.org>

This commit replaces a nested ?: sequence with clamp().  This does not
reduce the number of lines of code, but it does simplify the line that
it modifies.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 kernel/rcu/tree.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 55df6d37145e..e46a5124c3eb 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -2584,7 +2584,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
 		const long npj = NSEC_PER_SEC / HZ;
 		long rrn = READ_ONCE(rcu_resched_ns);
 
-		rrn = rrn < NSEC_PER_MSEC ? NSEC_PER_MSEC : rrn > NSEC_PER_SEC ? NSEC_PER_SEC : rrn;
+		rrn = clamp(rrn, NSEC_PER_MSEC, NSEC_PER_SEC);
 		tlimit = local_clock() + rrn;
 		jlimit = jiffies + (rrn + npj + 1) / npj;
 		jlimit_check = true;
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 08/11] rcu: Simplify param_set_next_fqs_jiffies() by applying clamp_val()
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
                   ` (6 preceding siblings ...)
  2026-05-19 19:45 ` [PATCH -next v2 07/11] rcu: Simplify rcu_do_batch() by applying clamp() Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-20 12:31   ` Frederic Weisbecker
  2026-05-19 19:45 ` [PATCH -next v2 09/11] rcu: Document rcu_access_pointer() feeding into cmpxchg() Uladzislau Rezki (Sony)
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki

From: "Paul E. McKenney" <paulmck@kernel.org>

This commit replaces a nested ?: sequence with clamp_val().  This does
not reduce the number of lines of code, but it does simplify the line
that it modifies.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 kernel/rcu/tree.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index e46a5124c3eb..09f0cef5014c 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -492,7 +492,7 @@ static int param_set_next_fqs_jiffies(const char *val, const struct kernel_param
 	int ret = kstrtoul(val, 0, &j);
 
 	if (!ret) {
-		WRITE_ONCE(*(ulong *)kp->arg, (j > HZ) ? HZ : (j ?: 1));
+		WRITE_ONCE(*(ulong *)kp->arg, clamp_val(j, 1, HZ));
 		adjust_jiffies_till_sched_qs();
 	}
 	return ret;
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 09/11] rcu: Document rcu_access_pointer() feeding into cmpxchg()
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
                   ` (7 preceding siblings ...)
  2026-05-19 19:45 ` [PATCH -next v2 08/11] rcu: Simplify param_set_next_fqs_jiffies() by applying clamp_val() Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-20 12:44   ` Frederic Weisbecker
  2026-05-19 19:45 ` [PATCH -next v2 10/11] rcu: Latch normal synchronize_rcu() path on flood Uladzislau Rezki (Sony)
  2026-05-19 19:45 ` [PATCH -next v2 11/11] rcu-tasks: Fix possible boot-time tests failed for the call_rcu_tasks() Uladzislau Rezki (Sony)
  10 siblings, 1 reply; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki, Maxim Mikityanskiy

From: "Paul E. McKenney" <paulmck@kernel.org>

This commit documents the rcu_access_pointer() use case for fetching the
old value of an RCU-protected pointer within a lockless updater for use
by an atomic cmpxchg() operation.

Reported-by: Maxim Mikityanskiy <maximmi@nvidia.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 include/linux/rcupdate.h | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index bfa765132de8..5e95acc33989 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -592,11 +592,13 @@ context_unsafe(							      \
  * lockdep checks for being in an RCU read-side critical section.  This is
  * useful when the value of this pointer is accessed, but the pointer is
  * not dereferenced, for example, when testing an RCU-protected pointer
- * against NULL.  Although rcu_access_pointer() may also be used in cases
- * where update-side locks prevent the value of the pointer from changing,
- * you should instead use rcu_dereference_protected() for this use case.
- * Within an RCU read-side critical section, there is little reason to
- * use rcu_access_pointer().
+ * against NULL.  Within an RCU read-side critical section, there is little
+ * reason to use rcu_access_pointer().  Although rcu_access_pointer() may
+ * also be used in cases where update-side locks prevent the value of the
+ * pointer from changing, you should instead use rcu_dereference_protected()
+ * for this use case.  It is also permissible to use rcu_access_pointer()
+ * within lockless updaters to obtain the old value for an atomic operation,
+ * for example, for cmpxchg().
  *
  * It is usually best to test the rcu_access_pointer() return value
  * directly in order to avoid accidental dereferences being introduced
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 10/11] rcu: Latch normal synchronize_rcu() path on flood
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
                   ` (8 preceding siblings ...)
  2026-05-19 19:45 ` [PATCH -next v2 09/11] rcu: Document rcu_access_pointer() feeding into cmpxchg() Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  2026-05-20 14:43   ` Frederic Weisbecker
  2026-05-19 19:45 ` [PATCH -next v2 11/11] rcu-tasks: Fix possible boot-time tests failed for the call_rcu_tasks() Uladzislau Rezki (Sony)
  10 siblings, 1 reply; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki, Samir M

Currently, rcu_normal_wake_from_gp is only enabled by default
on small systems(<= 16 CPUs) or when a user explicitly set it
enabled.

Introduce an adaptive latching mechanism:
 * Track the number of in-flight synchronize_rcu() requests
   using a new rcu_sr_normal_count counter;

 * If the count reaches/exceeds RCU_SR_NORMAL_LATCH_THR(64),
   it sets the rcu_sr_normal_latched, reverting new requests
   onto the scaled wait_rcu_gp() path;

 * The latch is cleared only when the pending requests are fully
   drained(nr == 0);

 * Enables rcu_normal_wake_from_gp by default for all systems,
   relying on this dynamic throttling instead of static CPU
   limits.

Testing(synthetic flood workload):
  * Kernel version: 6.19.0-rc6
  * Number of CPUs: 1536
  * 60K concurrent synchronize_rcu() calls

Perf(cycles, system-wide):
  total cycles: 932020263832
  rcu_sr_normal_add_req(): 2650282811 cycles(~0.28%)

Perf report excerpt:
  0.01%  0.01%  sync_test/...  [k] rcu_sr_normal_add_req

Measured overhead of rcu_sr_normal_add_req() remained ~0.28%
of total CPU cycles in this synthetic stress test.

Tested-by: Samir M <samir@linux.ibm.com>
Suggested-by: Joel Fernandes <joelagnelf@nvidia.com>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 .../admin-guide/kernel-parameters.txt         | 10 ++--
 kernel/rcu/tree.c                             | 52 ++++++++++++++-----
 2 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 4d0f545fb3ec..d5db2e85d551 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5862,13 +5862,13 @@ Kernel parameters
 			use a call_rcu[_hurry]() path. Please note, this is for a
 			normal grace period.
 
-			How to enable it:
+			How to disable it:
 
-			echo 1 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
-			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=1"
+			echo 0 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
+			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=0"
 
-			Default is 1 if num_possible_cpus() <= 16 and it is not explicitly
-			disabled by the boot parameter passing 0.
+			Default is 1 if it is not explicitly disabled by the boot parameter
+			passing 0.
 
 	rcuscale.gp_async= [KNL]
 			Measure performance of asynchronous
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 09f0cef5014c..94274330d1db 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1632,17 +1632,21 @@ static void rcu_sr_put_wait_head(struct llist_node *node)
 	atomic_set_release(&sr_wn->inuse, 0);
 }
 
-/* Enable rcu_normal_wake_from_gp automatically on small systems. */
-#define WAKE_FROM_GP_CPU_THRESHOLD 16
-
-static int rcu_normal_wake_from_gp = -1;
+static int rcu_normal_wake_from_gp = 1;
 module_param(rcu_normal_wake_from_gp, int, 0644);
 static struct workqueue_struct *sync_wq;
 
+#define RCU_SR_NORMAL_LATCH_THR 64
+
+/* Number of in-flight synchronize_rcu() calls queued on srs_next. */
+static atomic_long_t rcu_sr_normal_count;
+static int rcu_sr_normal_latched; /* 0/1 */
+
 static void rcu_sr_normal_complete(struct llist_node *node)
 {
 	struct rcu_synchronize *rs = container_of(
 		(struct rcu_head *) node, struct rcu_synchronize, head);
+	long nr;
 
 	WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) &&
 		!poll_state_synchronize_rcu_full(&rs->oldstate),
@@ -1650,6 +1654,15 @@ static void rcu_sr_normal_complete(struct llist_node *node)
 
 	/* Finally. */
 	complete(&rs->completion);
+	nr = atomic_long_dec_return(&rcu_sr_normal_count);
+	WARN_ON_ONCE(nr < 0);
+
+	/*
+	 * Unlatch: switch back to normal path when fully
+	 * drained and if it has been latched.
+	 */
+	if (nr == 0)
+		(void)cmpxchg(&rcu_sr_normal_latched, 1, 0);
 }
 
 static void rcu_sr_normal_gp_cleanup_work(struct work_struct *work)
@@ -1795,6 +1808,24 @@ static bool rcu_sr_normal_gp_init(void)
 
 static void rcu_sr_normal_add_req(struct rcu_synchronize *rs)
 {
+	/*
+	 * Increment before publish to avoid a complete
+	 * vs enqueue race on latch.
+	 */
+	long nr = atomic_long_inc_return(&rcu_sr_normal_count);
+
+	/*
+	 * Latch when threshold is reached. Checking for an exact match
+	 * restricts cmpxchg() to a single context.
+	 *
+	 * This latch is intentionally relaxed and best-effort. Concurrent
+	 * set/clear can race and temporarily lose the latch, which is OK
+	 * because it only selects between the fast and fallback paths.
+	 */
+	if (nr == RCU_SR_NORMAL_LATCH_THR)
+		(void)cmpxchg(&rcu_sr_normal_latched, 0, 1);
+
+	/* Publish for the GP kthread/worker. */
 	llist_add((struct llist_node *) &rs->head, &rcu_state.srs_next);
 }
 
@@ -3278,14 +3309,15 @@ static void synchronize_rcu_normal(void)
 {
 	struct rcu_synchronize rs;
 
+	init_rcu_head_on_stack(&rs.head);
 	trace_rcu_sr_normal(rcu_state.name, &rs.head, TPS("request"));
 
-	if (READ_ONCE(rcu_normal_wake_from_gp) < 1) {
+	if (READ_ONCE(rcu_normal_wake_from_gp) < 1 ||
+			READ_ONCE(rcu_sr_normal_latched)) {
 		wait_rcu_gp(call_rcu_hurry);
 		goto trace_complete_out;
 	}
 
-	init_rcu_head_on_stack(&rs.head);
 	init_completion(&rs.completion);
 
 	/*
@@ -3302,10 +3334,10 @@ static void synchronize_rcu_normal(void)
 
 	/* Now we can wait. */
 	wait_for_completion(&rs.completion);
-	destroy_rcu_head_on_stack(&rs.head);
 
 trace_complete_out:
 	trace_rcu_sr_normal(rcu_state.name, &rs.head, TPS("complete"));
+	destroy_rcu_head_on_stack(&rs.head);
 }
 
 /**
@@ -4904,12 +4936,6 @@ void __init rcu_init(void)
 	sync_wq = alloc_workqueue("sync_wq", WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
 	WARN_ON(!sync_wq);
 
-	/* Respect if explicitly disabled via a boot parameter. */
-	if (rcu_normal_wake_from_gp < 0) {
-		if (num_possible_cpus() <= WAKE_FROM_GP_CPU_THRESHOLD)
-			rcu_normal_wake_from_gp = 1;
-	}
-
 	/* Fill in default value for rcutree.qovld boot parameter. */
 	/* -After- the rcu_node ->lock fields are initialized! */
 	if (qovld < 0)
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH -next v2 11/11] rcu-tasks: Fix possible boot-time tests failed for the call_rcu_tasks()
  2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
                   ` (9 preceding siblings ...)
  2026-05-19 19:45 ` [PATCH -next v2 10/11] rcu: Latch normal synchronize_rcu() path on flood Uladzislau Rezki (Sony)
@ 2026-05-19 19:45 ` Uladzislau Rezki (Sony)
  10 siblings, 0 replies; 20+ messages in thread
From: Uladzislau Rezki (Sony) @ 2026-05-19 19:45 UTC (permalink / raw)
  To: Paul E . McKenney, Joel Fernandes, Frederic Weisbecker,
	Boqun Feng
  Cc: RCU, LKML, Uladzislau Rezki, Zqiang

From: Zqiang <qiang.zhang@linux.dev>

The following scenarios will cause the call_rcu_tasks() boot-time
tests failed:

                     CPU0								CPU1

rcu_init_tasks_generic()
->rcu_tasks_initiate_self_tests()
  ->call_rcu_tasks_trace(&tests[1].rh, test_rcu_tasks_callback)
    ->call_rcu_tasks_generic()
      ->havekthread = smp_load_acquire(&rtp->kthread_ptr)
       "The havekthread is false"
    ....
								       rcu_tasks_kthread()
								       ->smp_store_release(&rtp->kthread_ptr, current)
								         ->rcu_tasks_one_gp()
								           ->rcuwait_wait_event()
								             ->rcu_tasks_need_gpcb()
								               ->for (cpu = 0; cpu < dequeue_limit; cpu++)
								                 ->rcu_segcblist_n_cbs(&rtpcp->cblist) == 0
								           ->schedule()

     ->raw_spin_trylock_rcu_node()
     ->needwake = (func == wakeme_after_rcu) ||
     (rcu_segcblist_n_cbs(&rtpcp->cblist) == rcu_task_lazy_lim)

       "the rcu_task_lazy_lim default value is 32, and the
        func pointer is test_rcu_tasks_callback, lead to needwake
        is false."

     ->if (havekthread && !needwake && !timer_pending(&rtpcp->lazy_timer))
        "the havekthread is false, will not enter here."
     ....

        "the needwake is false lead to rtp_irq_work can not queue,
         even if the rtp->kthread_ptr already exists at this point."

      ->if (needwake && READ_ONCE(rtp->kthread_ptr))
        ->irq_work_queue(&rtpcp->rtp_irq_work)

For the above scenarios, if the call_rcu_tasks() is not called again
afterward, the rcu_tasks_kthread will not have a chance to be wakeup,
the test_rcu_tasks_callback() will never be called, the boot-time tests
failed can happen, this commit therefore check havekthread variable, if
it's false and the rtpcp->cblist is empty, set needwake variable is true,
if the rtp->kthread_ptr exist, the rtpcp->rtp_irq_work can be queued to
wakeup rcu_tasks_kthread.

Signed-off-by: Zqiang <qiang.zhang@linux.dev>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
 kernel/rcu/tasks.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
index 48f0d803c8e2..f4da5fad70f5 100644
--- a/kernel/rcu/tasks.h
+++ b/kernel/rcu/tasks.h
@@ -373,7 +373,8 @@ static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func,
 	// Queuing callbacks before initialization not yet supported.
 	if (WARN_ON_ONCE(!rcu_segcblist_is_enabled(&rtpcp->cblist)))
 		rcu_segcblist_init(&rtpcp->cblist);
-	needwake = (func == wakeme_after_rcu) ||
+	needwake = (!havekthread && rcu_segcblist_empty(&rtpcp->cblist)) ||
+		   (func == wakeme_after_rcu) ||
 		   (rcu_segcblist_n_cbs(&rtpcp->cblist) == rcu_task_lazy_lim);
 	if (havekthread && !needwake && !timer_pending(&rtpcp->lazy_timer)) {
 		if (rtp->lazy_jiffies)
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH -next v2 07/11] rcu: Simplify rcu_do_batch() by applying clamp()
  2026-05-19 19:45 ` [PATCH -next v2 07/11] rcu: Simplify rcu_do_batch() by applying clamp() Uladzislau Rezki (Sony)
@ 2026-05-20 12:26   ` Frederic Weisbecker
  2026-05-20 13:54     ` Uladzislau Rezki
  0 siblings, 1 reply; 20+ messages in thread
From: Frederic Weisbecker @ 2026-05-20 12:26 UTC (permalink / raw)
  To: Uladzislau Rezki (Sony)
  Cc: Paul E . McKenney, Joel Fernandes, Boqun Feng, RCU, LKML

Le Tue, May 19, 2026 at 09:45:20PM +0200, Uladzislau Rezki (Sony) a écrit :
> From: "Paul E. McKenney" <paulmck@kernel.org>
> 
> This commit replaces a nested ?: sequence with clamp().  This does not
> reduce the number of lines of code, but it does simplify the line that
> it modifies.
> 
> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>

Reviewed-by: Frederic Weisbecker <frederic@kernel.org>


> ---
>  kernel/rcu/tree.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index 55df6d37145e..e46a5124c3eb 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -2584,7 +2584,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
>  		const long npj = NSEC_PER_SEC / HZ;
>  		long rrn = READ_ONCE(rcu_resched_ns);
>  
> -		rrn = rrn < NSEC_PER_MSEC ? NSEC_PER_MSEC : rrn > NSEC_PER_SEC ? NSEC_PER_SEC : rrn;
> +		rrn = clamp(rrn, NSEC_PER_MSEC, NSEC_PER_SEC);
>  		tlimit = local_clock() + rrn;
>  		jlimit = jiffies + (rrn + npj + 1) / npj;
>  		jlimit_check = true;
> -- 
> 2.47.3
> 
> 

-- 
Frederic Weisbecker
SUSE Labs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH -next v2 08/11] rcu: Simplify param_set_next_fqs_jiffies() by applying clamp_val()
  2026-05-19 19:45 ` [PATCH -next v2 08/11] rcu: Simplify param_set_next_fqs_jiffies() by applying clamp_val() Uladzislau Rezki (Sony)
@ 2026-05-20 12:31   ` Frederic Weisbecker
  0 siblings, 0 replies; 20+ messages in thread
From: Frederic Weisbecker @ 2026-05-20 12:31 UTC (permalink / raw)
  To: Uladzislau Rezki (Sony)
  Cc: Paul E . McKenney, Joel Fernandes, Boqun Feng, RCU, LKML

Le Tue, May 19, 2026 at 09:45:21PM +0200, Uladzislau Rezki (Sony) a écrit :
> From: "Paul E. McKenney" <paulmck@kernel.org>
> 
> This commit replaces a nested ?: sequence with clamp_val().  This does
> not reduce the number of lines of code, but it does simplify the line
> that it modifies.
> 
> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>

Reviewed-by: Frederic Weisbecker <frederic@kernel.org>


> ---
>  kernel/rcu/tree.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index e46a5124c3eb..09f0cef5014c 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -492,7 +492,7 @@ static int param_set_next_fqs_jiffies(const char *val, const struct kernel_param
>  	int ret = kstrtoul(val, 0, &j);
>  
>  	if (!ret) {
> -		WRITE_ONCE(*(ulong *)kp->arg, (j > HZ) ? HZ : (j ?: 1));
> +		WRITE_ONCE(*(ulong *)kp->arg, clamp_val(j, 1, HZ));
>  		adjust_jiffies_till_sched_qs();
>  	}
>  	return ret;
> -- 
> 2.47.3
> 
> 

-- 
Frederic Weisbecker
SUSE Labs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH -next v2 09/11] rcu: Document rcu_access_pointer() feeding into cmpxchg()
  2026-05-19 19:45 ` [PATCH -next v2 09/11] rcu: Document rcu_access_pointer() feeding into cmpxchg() Uladzislau Rezki (Sony)
@ 2026-05-20 12:44   ` Frederic Weisbecker
  0 siblings, 0 replies; 20+ messages in thread
From: Frederic Weisbecker @ 2026-05-20 12:44 UTC (permalink / raw)
  To: Uladzislau Rezki (Sony)
  Cc: Paul E . McKenney, Joel Fernandes, Boqun Feng, RCU, LKML,
	Maxim Mikityanskiy

Le Tue, May 19, 2026 at 09:45:22PM +0200, Uladzislau Rezki (Sony) a écrit :
> From: "Paul E. McKenney" <paulmck@kernel.org>
> 
> This commit documents the rcu_access_pointer() use case for fetching the
> old value of an RCU-protected pointer within a lockless updater for use
> by an atomic cmpxchg() operation.
> 
> Reported-by: Maxim Mikityanskiy <maximmi@nvidia.com>
> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>

Reviewed-by: Frederic Weisbecker <frederic@kernel.org>

-- 
Frederic Weisbecker
SUSE Labs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH -next v2 07/11] rcu: Simplify rcu_do_batch() by applying clamp()
  2026-05-20 12:26   ` Frederic Weisbecker
@ 2026-05-20 13:54     ` Uladzislau Rezki
  0 siblings, 0 replies; 20+ messages in thread
From: Uladzislau Rezki @ 2026-05-20 13:54 UTC (permalink / raw)
  To: Frederic Weisbecker
  Cc: Uladzislau Rezki (Sony), Paul E . McKenney, Joel Fernandes,
	Boqun Feng, RCU, LKML

On Wed, May 20, 2026 at 02:26:47PM +0200, Frederic Weisbecker wrote:
> Le Tue, May 19, 2026 at 09:45:20PM +0200, Uladzislau Rezki (Sony) a écrit :
> > From: "Paul E. McKenney" <paulmck@kernel.org>
> > 
> > This commit replaces a nested ?: sequence with clamp().  This does not
> > reduce the number of lines of code, but it does simplify the line that
> > it modifies.
> > 
> > Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> > Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
> 
> Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
> 
Applied Reviewed-by tag!

--
Uladzislau Rezki

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH -next v2 10/11] rcu: Latch normal synchronize_rcu() path on flood
  2026-05-19 19:45 ` [PATCH -next v2 10/11] rcu: Latch normal synchronize_rcu() path on flood Uladzislau Rezki (Sony)
@ 2026-05-20 14:43   ` Frederic Weisbecker
  2026-05-20 15:16     ` Uladzislau Rezki
  0 siblings, 1 reply; 20+ messages in thread
From: Frederic Weisbecker @ 2026-05-20 14:43 UTC (permalink / raw)
  To: Uladzislau Rezki (Sony)
  Cc: Paul E . McKenney, Joel Fernandes, Boqun Feng, RCU, LKML, Samir M

Le Tue, May 19, 2026 at 09:45:23PM +0200, Uladzislau Rezki (Sony) a écrit :
> Currently, rcu_normal_wake_from_gp is only enabled by default
> on small systems(<= 16 CPUs) or when a user explicitly set it
> enabled.
> 
> Introduce an adaptive latching mechanism:
>  * Track the number of in-flight synchronize_rcu() requests
>    using a new rcu_sr_normal_count counter;
> 
>  * If the count reaches/exceeds RCU_SR_NORMAL_LATCH_THR(64),
>    it sets the rcu_sr_normal_latched, reverting new requests
>    onto the scaled wait_rcu_gp() path;
> 
>  * The latch is cleared only when the pending requests are fully
>    drained(nr == 0);
> 
>  * Enables rcu_normal_wake_from_gp by default for all systems,
>    relying on this dynamic throttling instead of static CPU
>    limits.
> 
> Testing(synthetic flood workload):
>   * Kernel version: 6.19.0-rc6
>   * Number of CPUs: 1536
>   * 60K concurrent synchronize_rcu() calls
> 
> Perf(cycles, system-wide):
>   total cycles: 932020263832
>   rcu_sr_normal_add_req(): 2650282811 cycles(~0.28%)
> 
> Perf report excerpt:
>   0.01%  0.01%  sync_test/...  [k] rcu_sr_normal_add_req
> 
> Measured overhead of rcu_sr_normal_add_req() remained ~0.28%
> of total CPU cycles in this synthetic stress test.
> 
> Tested-by: Samir M <samir@linux.ibm.com>
> Suggested-by: Joel Fernandes <joelagnelf@nvidia.com>
> Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
> ---
>  .../admin-guide/kernel-parameters.txt         | 10 ++--
>  kernel/rcu/tree.c                             | 52 ++++++++++++++-----
>  2 files changed, 44 insertions(+), 18 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 4d0f545fb3ec..d5db2e85d551 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -5862,13 +5862,13 @@ Kernel parameters
>  			use a call_rcu[_hurry]() path. Please note, this is for a
>  			normal grace period.
>  
> -			How to enable it:
> +			How to disable it:
>  
> -			echo 1 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
> -			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=1"
> +			echo 0 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
> +			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=0"
>  
> -			Default is 1 if num_possible_cpus() <= 16 and it is not explicitly
> -			disabled by the boot parameter passing 0.
> +			Default is 1 if it is not explicitly disabled by the boot parameter
> +			passing 0.
>  
>  	rcuscale.gp_async= [KNL]
>  			Measure performance of asynchronous
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index 09f0cef5014c..94274330d1db 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -1632,17 +1632,21 @@ static void rcu_sr_put_wait_head(struct llist_node *node)
>  	atomic_set_release(&sr_wn->inuse, 0);
>  }
>  
> -/* Enable rcu_normal_wake_from_gp automatically on small systems. */
> -#define WAKE_FROM_GP_CPU_THRESHOLD 16
> -
> -static int rcu_normal_wake_from_gp = -1;
> +static int rcu_normal_wake_from_gp = 1;
>  module_param(rcu_normal_wake_from_gp, int, 0644);
>  static struct workqueue_struct *sync_wq;
>  
> +#define RCU_SR_NORMAL_LATCH_THR 64
> +
> +/* Number of in-flight synchronize_rcu() calls queued on srs_next. */
> +static atomic_long_t rcu_sr_normal_count;
> +static int rcu_sr_normal_latched; /* 0/1 */
> +
>  static void rcu_sr_normal_complete(struct llist_node *node)
>  {
>  	struct rcu_synchronize *rs = container_of(
>  		(struct rcu_head *) node, struct rcu_synchronize, head);
> +	long nr;
>  
>  	WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) &&
>  		!poll_state_synchronize_rcu_full(&rs->oldstate),
> @@ -1650,6 +1654,15 @@ static void rcu_sr_normal_complete(struct llist_node *node)
>  
>  	/* Finally. */
>  	complete(&rs->completion);
> +	nr = atomic_long_dec_return(&rcu_sr_normal_count);
> +	WARN_ON_ONCE(nr < 0);
> +
> +	/*
> +	 * Unlatch: switch back to normal path when fully
> +	 * drained and if it has been latched.
> +	 */
> +	if (nr == 0)
> +		(void)cmpxchg(&rcu_sr_normal_latched, 1, 0);

Given that it's already ordered by the llist add / del and the
atomic_long_inc/dec_return, there should be no chance for bad
things happening such as negative returned dec.

So it could be cmpxchg_relaxed(). But anyway, just an optimization.

In any case,

Reviewed-by: Frederic Weisbecker <frederic@kernel.org>

-- 
Frederic Weisbecker
SUSE Labs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH -next v2 10/11] rcu: Latch normal synchronize_rcu() path on flood
  2026-05-20 14:43   ` Frederic Weisbecker
@ 2026-05-20 15:16     ` Uladzislau Rezki
  2026-05-20 22:28       ` Frederic Weisbecker
  0 siblings, 1 reply; 20+ messages in thread
From: Uladzislau Rezki @ 2026-05-20 15:16 UTC (permalink / raw)
  To: Frederic Weisbecker
  Cc: Uladzislau Rezki (Sony), Paul E . McKenney, Joel Fernandes,
	Boqun Feng, RCU, LKML, Samir M

On Wed, May 20, 2026 at 04:43:18PM +0200, Frederic Weisbecker wrote:
> Le Tue, May 19, 2026 at 09:45:23PM +0200, Uladzislau Rezki (Sony) a écrit :
> > Currently, rcu_normal_wake_from_gp is only enabled by default
> > on small systems(<= 16 CPUs) or when a user explicitly set it
> > enabled.
> > 
> > Introduce an adaptive latching mechanism:
> >  * Track the number of in-flight synchronize_rcu() requests
> >    using a new rcu_sr_normal_count counter;
> > 
> >  * If the count reaches/exceeds RCU_SR_NORMAL_LATCH_THR(64),
> >    it sets the rcu_sr_normal_latched, reverting new requests
> >    onto the scaled wait_rcu_gp() path;
> > 
> >  * The latch is cleared only when the pending requests are fully
> >    drained(nr == 0);
> > 
> >  * Enables rcu_normal_wake_from_gp by default for all systems,
> >    relying on this dynamic throttling instead of static CPU
> >    limits.
> > 
> > Testing(synthetic flood workload):
> >   * Kernel version: 6.19.0-rc6
> >   * Number of CPUs: 1536
> >   * 60K concurrent synchronize_rcu() calls
> > 
> > Perf(cycles, system-wide):
> >   total cycles: 932020263832
> >   rcu_sr_normal_add_req(): 2650282811 cycles(~0.28%)
> > 
> > Perf report excerpt:
> >   0.01%  0.01%  sync_test/...  [k] rcu_sr_normal_add_req
> > 
> > Measured overhead of rcu_sr_normal_add_req() remained ~0.28%
> > of total CPU cycles in this synthetic stress test.
> > 
> > Tested-by: Samir M <samir@linux.ibm.com>
> > Suggested-by: Joel Fernandes <joelagnelf@nvidia.com>
> > Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
> > ---
> >  .../admin-guide/kernel-parameters.txt         | 10 ++--
> >  kernel/rcu/tree.c                             | 52 ++++++++++++++-----
> >  2 files changed, 44 insertions(+), 18 deletions(-)
> > 
> > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> > index 4d0f545fb3ec..d5db2e85d551 100644
> > --- a/Documentation/admin-guide/kernel-parameters.txt
> > +++ b/Documentation/admin-guide/kernel-parameters.txt
> > @@ -5862,13 +5862,13 @@ Kernel parameters
> >  			use a call_rcu[_hurry]() path. Please note, this is for a
> >  			normal grace period.
> >  
> > -			How to enable it:
> > +			How to disable it:
> >  
> > -			echo 1 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
> > -			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=1"
> > +			echo 0 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
> > +			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=0"
> >  
> > -			Default is 1 if num_possible_cpus() <= 16 and it is not explicitly
> > -			disabled by the boot parameter passing 0.
> > +			Default is 1 if it is not explicitly disabled by the boot parameter
> > +			passing 0.
> >  
> >  	rcuscale.gp_async= [KNL]
> >  			Measure performance of asynchronous
> > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > index 09f0cef5014c..94274330d1db 100644
> > --- a/kernel/rcu/tree.c
> > +++ b/kernel/rcu/tree.c
> > @@ -1632,17 +1632,21 @@ static void rcu_sr_put_wait_head(struct llist_node *node)
> >  	atomic_set_release(&sr_wn->inuse, 0);
> >  }
> >  
> > -/* Enable rcu_normal_wake_from_gp automatically on small systems. */
> > -#define WAKE_FROM_GP_CPU_THRESHOLD 16
> > -
> > -static int rcu_normal_wake_from_gp = -1;
> > +static int rcu_normal_wake_from_gp = 1;
> >  module_param(rcu_normal_wake_from_gp, int, 0644);
> >  static struct workqueue_struct *sync_wq;
> >  
> > +#define RCU_SR_NORMAL_LATCH_THR 64
> > +
> > +/* Number of in-flight synchronize_rcu() calls queued on srs_next. */
> > +static atomic_long_t rcu_sr_normal_count;
> > +static int rcu_sr_normal_latched; /* 0/1 */
> > +
> >  static void rcu_sr_normal_complete(struct llist_node *node)
> >  {
> >  	struct rcu_synchronize *rs = container_of(
> >  		(struct rcu_head *) node, struct rcu_synchronize, head);
> > +	long nr;
> >  
> >  	WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) &&
> >  		!poll_state_synchronize_rcu_full(&rs->oldstate),
> > @@ -1650,6 +1654,15 @@ static void rcu_sr_normal_complete(struct llist_node *node)
> >  
> >  	/* Finally. */
> >  	complete(&rs->completion);
> > +	nr = atomic_long_dec_return(&rcu_sr_normal_count);
> > +	WARN_ON_ONCE(nr < 0);
> > +
> > +	/*
> > +	 * Unlatch: switch back to normal path when fully
> > +	 * drained and if it has been latched.
> > +	 */
> > +	if (nr == 0)
> > +		(void)cmpxchg(&rcu_sr_normal_latched, 1, 0);
> 
> Given that it's already ordered by the llist add / del and the
> atomic_long_inc/dec_return, there should be no chance for bad
> things happening such as negative returned dec.
> 
> So it could be cmpxchg_relaxed(). But anyway, just an optimization.
> 
> In any case,
> 
> Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
> 
Hello, Frederic!

I change it accordingly, please check!

diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 94274330d1db..2c76b59f75de 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1655,14 +1655,13 @@ static void rcu_sr_normal_complete(struct llist_node *node)
 	/* Finally. */
 	complete(&rs->completion);
 	nr = atomic_long_dec_return(&rcu_sr_normal_count);
-	WARN_ON_ONCE(nr < 0);
 
 	/*
 	 * Unlatch: switch back to normal path when fully
 	 * drained and if it has been latched.
 	 */
 	if (nr == 0)
-		(void)cmpxchg(&rcu_sr_normal_latched, 1, 0);
+		(void)cmpxchg_relaxed(&rcu_sr_normal_latched, 1, 0);
 }
 
 static void rcu_sr_normal_gp_cleanup_work(struct work_struct *work)
@@ -1823,7 +1822,7 @@ static void rcu_sr_normal_add_req(struct rcu_synchronize *rs)
 	 * because it only selects between the fast and fallback paths.
 	 */
 	if (nr == RCU_SR_NORMAL_LATCH_THR)
-		(void)cmpxchg(&rcu_sr_normal_latched, 0, 1);
+		(void)cmpxchg_relaxed(&rcu_sr_normal_latched, 0, 1);
 
 	/* Publish for the GP kthread/worker. */
 	llist_add((struct llist_node *) &rs->head, &rcu_state.srs_next);

Sounds good?

--
Uladzislau Rezki

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH -next v2 10/11] rcu: Latch normal synchronize_rcu() path on flood
  2026-05-20 15:16     ` Uladzislau Rezki
@ 2026-05-20 22:28       ` Frederic Weisbecker
  2026-05-21  5:23         ` Uladzislau Rezki
  0 siblings, 1 reply; 20+ messages in thread
From: Frederic Weisbecker @ 2026-05-20 22:28 UTC (permalink / raw)
  To: Uladzislau Rezki
  Cc: Paul E . McKenney, Joel Fernandes, Boqun Feng, RCU, LKML, Samir M

Le Wed, May 20, 2026 at 05:16:19PM +0200, Uladzislau Rezki a écrit :
> On Wed, May 20, 2026 at 04:43:18PM +0200, Frederic Weisbecker wrote:
> > Le Tue, May 19, 2026 at 09:45:23PM +0200, Uladzislau Rezki (Sony) a écrit :
> > > Currently, rcu_normal_wake_from_gp is only enabled by default
> > > on small systems(<= 16 CPUs) or when a user explicitly set it
> > > enabled.
> > > 
> > > Introduce an adaptive latching mechanism:
> > >  * Track the number of in-flight synchronize_rcu() requests
> > >    using a new rcu_sr_normal_count counter;
> > > 
> > >  * If the count reaches/exceeds RCU_SR_NORMAL_LATCH_THR(64),
> > >    it sets the rcu_sr_normal_latched, reverting new requests
> > >    onto the scaled wait_rcu_gp() path;
> > > 
> > >  * The latch is cleared only when the pending requests are fully
> > >    drained(nr == 0);
> > > 
> > >  * Enables rcu_normal_wake_from_gp by default for all systems,
> > >    relying on this dynamic throttling instead of static CPU
> > >    limits.
> > > 
> > > Testing(synthetic flood workload):
> > >   * Kernel version: 6.19.0-rc6
> > >   * Number of CPUs: 1536
> > >   * 60K concurrent synchronize_rcu() calls
> > > 
> > > Perf(cycles, system-wide):
> > >   total cycles: 932020263832
> > >   rcu_sr_normal_add_req(): 2650282811 cycles(~0.28%)
> > > 
> > > Perf report excerpt:
> > >   0.01%  0.01%  sync_test/...  [k] rcu_sr_normal_add_req
> > > 
> > > Measured overhead of rcu_sr_normal_add_req() remained ~0.28%
> > > of total CPU cycles in this synthetic stress test.
> > > 
> > > Tested-by: Samir M <samir@linux.ibm.com>
> > > Suggested-by: Joel Fernandes <joelagnelf@nvidia.com>
> > > Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
> > > ---
> > >  .../admin-guide/kernel-parameters.txt         | 10 ++--
> > >  kernel/rcu/tree.c                             | 52 ++++++++++++++-----
> > >  2 files changed, 44 insertions(+), 18 deletions(-)
> > > 
> > > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> > > index 4d0f545fb3ec..d5db2e85d551 100644
> > > --- a/Documentation/admin-guide/kernel-parameters.txt
> > > +++ b/Documentation/admin-guide/kernel-parameters.txt
> > > @@ -5862,13 +5862,13 @@ Kernel parameters
> > >  			use a call_rcu[_hurry]() path. Please note, this is for a
> > >  			normal grace period.
> > >  
> > > -			How to enable it:
> > > +			How to disable it:
> > >  
> > > -			echo 1 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
> > > -			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=1"
> > > +			echo 0 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
> > > +			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=0"
> > >  
> > > -			Default is 1 if num_possible_cpus() <= 16 and it is not explicitly
> > > -			disabled by the boot parameter passing 0.
> > > +			Default is 1 if it is not explicitly disabled by the boot parameter
> > > +			passing 0.
> > >  
> > >  	rcuscale.gp_async= [KNL]
> > >  			Measure performance of asynchronous
> > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > > index 09f0cef5014c..94274330d1db 100644
> > > --- a/kernel/rcu/tree.c
> > > +++ b/kernel/rcu/tree.c
> > > @@ -1632,17 +1632,21 @@ static void rcu_sr_put_wait_head(struct llist_node *node)
> > >  	atomic_set_release(&sr_wn->inuse, 0);
> > >  }
> > >  
> > > -/* Enable rcu_normal_wake_from_gp automatically on small systems. */
> > > -#define WAKE_FROM_GP_CPU_THRESHOLD 16
> > > -
> > > -static int rcu_normal_wake_from_gp = -1;
> > > +static int rcu_normal_wake_from_gp = 1;
> > >  module_param(rcu_normal_wake_from_gp, int, 0644);
> > >  static struct workqueue_struct *sync_wq;
> > >  
> > > +#define RCU_SR_NORMAL_LATCH_THR 64
> > > +
> > > +/* Number of in-flight synchronize_rcu() calls queued on srs_next. */
> > > +static atomic_long_t rcu_sr_normal_count;
> > > +static int rcu_sr_normal_latched; /* 0/1 */
> > > +
> > >  static void rcu_sr_normal_complete(struct llist_node *node)
> > >  {
> > >  	struct rcu_synchronize *rs = container_of(
> > >  		(struct rcu_head *) node, struct rcu_synchronize, head);
> > > +	long nr;
> > >  
> > >  	WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) &&
> > >  		!poll_state_synchronize_rcu_full(&rs->oldstate),
> > > @@ -1650,6 +1654,15 @@ static void rcu_sr_normal_complete(struct llist_node *node)
> > >  
> > >  	/* Finally. */
> > >  	complete(&rs->completion);
> > > +	nr = atomic_long_dec_return(&rcu_sr_normal_count);
> > > +	WARN_ON_ONCE(nr < 0);
> > > +
> > > +	/*
> > > +	 * Unlatch: switch back to normal path when fully
> > > +	 * drained and if it has been latched.
> > > +	 */
> > > +	if (nr == 0)
> > > +		(void)cmpxchg(&rcu_sr_normal_latched, 1, 0);
> > 
> > Given that it's already ordered by the llist add / del and the
> > atomic_long_inc/dec_return, there should be no chance for bad
> > things happening such as negative returned dec.
> > 
> > So it could be cmpxchg_relaxed(). But anyway, just an optimization.
> > 
> > In any case,
> > 
> > Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
> > 
> Hello, Frederic!
> 
> I change it accordingly, please check!
> 
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index 94274330d1db..2c76b59f75de 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -1655,14 +1655,13 @@ static void rcu_sr_normal_complete(struct llist_node *node)
>  	/* Finally. */
>  	complete(&rs->completion);
>  	nr = atomic_long_dec_return(&rcu_sr_normal_count);
> -	WARN_ON_ONCE(nr < 0);

Why dropping this?

Otherwise yes, looks good!

Thanks!

>  
>  	/*
>  	 * Unlatch: switch back to normal path when fully
>  	 * drained and if it has been latched.
>  	 */
>  	if (nr == 0)
> -		(void)cmpxchg(&rcu_sr_normal_latched, 1, 0);
> +		(void)cmpxchg_relaxed(&rcu_sr_normal_latched, 1, 0);
>  }
>  
>  static void rcu_sr_normal_gp_cleanup_work(struct work_struct *work)
> @@ -1823,7 +1822,7 @@ static void rcu_sr_normal_add_req(struct rcu_synchronize *rs)
>  	 * because it only selects between the fast and fallback paths.
>  	 */
>  	if (nr == RCU_SR_NORMAL_LATCH_THR)
> -		(void)cmpxchg(&rcu_sr_normal_latched, 0, 1);
> +		(void)cmpxchg_relaxed(&rcu_sr_normal_latched, 0, 1);
>  
>  	/* Publish for the GP kthread/worker. */
>  	llist_add((struct llist_node *) &rs->head, &rcu_state.srs_next);
> 
> Sounds good?
> 
> --
> Uladzislau Rezki
> 

-- 
Frederic Weisbecker
SUSE Labs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH -next v2 10/11] rcu: Latch normal synchronize_rcu() path on flood
  2026-05-20 22:28       ` Frederic Weisbecker
@ 2026-05-21  5:23         ` Uladzislau Rezki
  0 siblings, 0 replies; 20+ messages in thread
From: Uladzislau Rezki @ 2026-05-21  5:23 UTC (permalink / raw)
  To: Frederic Weisbecker
  Cc: Uladzislau Rezki, Paul E . McKenney, Joel Fernandes, Boqun Feng,
	RCU, LKML, Samir M

On Thu, May 21, 2026 at 12:28:28AM +0200, Frederic Weisbecker wrote:
> Le Wed, May 20, 2026 at 05:16:19PM +0200, Uladzislau Rezki a écrit :
> > On Wed, May 20, 2026 at 04:43:18PM +0200, Frederic Weisbecker wrote:
> > > Le Tue, May 19, 2026 at 09:45:23PM +0200, Uladzislau Rezki (Sony) a écrit :
> > > > Currently, rcu_normal_wake_from_gp is only enabled by default
> > > > on small systems(<= 16 CPUs) or when a user explicitly set it
> > > > enabled.
> > > > 
> > > > Introduce an adaptive latching mechanism:
> > > >  * Track the number of in-flight synchronize_rcu() requests
> > > >    using a new rcu_sr_normal_count counter;
> > > > 
> > > >  * If the count reaches/exceeds RCU_SR_NORMAL_LATCH_THR(64),
> > > >    it sets the rcu_sr_normal_latched, reverting new requests
> > > >    onto the scaled wait_rcu_gp() path;
> > > > 
> > > >  * The latch is cleared only when the pending requests are fully
> > > >    drained(nr == 0);
> > > > 
> > > >  * Enables rcu_normal_wake_from_gp by default for all systems,
> > > >    relying on this dynamic throttling instead of static CPU
> > > >    limits.
> > > > 
> > > > Testing(synthetic flood workload):
> > > >   * Kernel version: 6.19.0-rc6
> > > >   * Number of CPUs: 1536
> > > >   * 60K concurrent synchronize_rcu() calls
> > > > 
> > > > Perf(cycles, system-wide):
> > > >   total cycles: 932020263832
> > > >   rcu_sr_normal_add_req(): 2650282811 cycles(~0.28%)
> > > > 
> > > > Perf report excerpt:
> > > >   0.01%  0.01%  sync_test/...  [k] rcu_sr_normal_add_req
> > > > 
> > > > Measured overhead of rcu_sr_normal_add_req() remained ~0.28%
> > > > of total CPU cycles in this synthetic stress test.
> > > > 
> > > > Tested-by: Samir M <samir@linux.ibm.com>
> > > > Suggested-by: Joel Fernandes <joelagnelf@nvidia.com>
> > > > Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
> > > > ---
> > > >  .../admin-guide/kernel-parameters.txt         | 10 ++--
> > > >  kernel/rcu/tree.c                             | 52 ++++++++++++++-----
> > > >  2 files changed, 44 insertions(+), 18 deletions(-)
> > > > 
> > > > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> > > > index 4d0f545fb3ec..d5db2e85d551 100644
> > > > --- a/Documentation/admin-guide/kernel-parameters.txt
> > > > +++ b/Documentation/admin-guide/kernel-parameters.txt
> > > > @@ -5862,13 +5862,13 @@ Kernel parameters
> > > >  			use a call_rcu[_hurry]() path. Please note, this is for a
> > > >  			normal grace period.
> > > >  
> > > > -			How to enable it:
> > > > +			How to disable it:
> > > >  
> > > > -			echo 1 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
> > > > -			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=1"
> > > > +			echo 0 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
> > > > +			or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=0"
> > > >  
> > > > -			Default is 1 if num_possible_cpus() <= 16 and it is not explicitly
> > > > -			disabled by the boot parameter passing 0.
> > > > +			Default is 1 if it is not explicitly disabled by the boot parameter
> > > > +			passing 0.
> > > >  
> > > >  	rcuscale.gp_async= [KNL]
> > > >  			Measure performance of asynchronous
> > > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > > > index 09f0cef5014c..94274330d1db 100644
> > > > --- a/kernel/rcu/tree.c
> > > > +++ b/kernel/rcu/tree.c
> > > > @@ -1632,17 +1632,21 @@ static void rcu_sr_put_wait_head(struct llist_node *node)
> > > >  	atomic_set_release(&sr_wn->inuse, 0);
> > > >  }
> > > >  
> > > > -/* Enable rcu_normal_wake_from_gp automatically on small systems. */
> > > > -#define WAKE_FROM_GP_CPU_THRESHOLD 16
> > > > -
> > > > -static int rcu_normal_wake_from_gp = -1;
> > > > +static int rcu_normal_wake_from_gp = 1;
> > > >  module_param(rcu_normal_wake_from_gp, int, 0644);
> > > >  static struct workqueue_struct *sync_wq;
> > > >  
> > > > +#define RCU_SR_NORMAL_LATCH_THR 64
> > > > +
> > > > +/* Number of in-flight synchronize_rcu() calls queued on srs_next. */
> > > > +static atomic_long_t rcu_sr_normal_count;
> > > > +static int rcu_sr_normal_latched; /* 0/1 */
> > > > +
> > > >  static void rcu_sr_normal_complete(struct llist_node *node)
> > > >  {
> > > >  	struct rcu_synchronize *rs = container_of(
> > > >  		(struct rcu_head *) node, struct rcu_synchronize, head);
> > > > +	long nr;
> > > >  
> > > >  	WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) &&
> > > >  		!poll_state_synchronize_rcu_full(&rs->oldstate),
> > > > @@ -1650,6 +1654,15 @@ static void rcu_sr_normal_complete(struct llist_node *node)
> > > >  
> > > >  	/* Finally. */
> > > >  	complete(&rs->completion);
> > > > +	nr = atomic_long_dec_return(&rcu_sr_normal_count);
> > > > +	WARN_ON_ONCE(nr < 0);
> > > > +
> > > > +	/*
> > > > +	 * Unlatch: switch back to normal path when fully
> > > > +	 * drained and if it has been latched.
> > > > +	 */
> > > > +	if (nr == 0)
> > > > +		(void)cmpxchg(&rcu_sr_normal_latched, 1, 0);
> > > 
> > > Given that it's already ordered by the llist add / del and the
> > > atomic_long_inc/dec_return, there should be no chance for bad
> > > things happening such as negative returned dec.
> > > 
> > > So it could be cmpxchg_relaxed(). But anyway, just an optimization.
> > > 
> > > In any case,
> > > 
> > > Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
> > > 
> > Hello, Frederic!
> > 
> > I change it accordingly, please check!
> > 
> > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > index 94274330d1db..2c76b59f75de 100644
> > --- a/kernel/rcu/tree.c
> > +++ b/kernel/rcu/tree.c
> > @@ -1655,14 +1655,13 @@ static void rcu_sr_normal_complete(struct llist_node *node)
> >  	/* Finally. */
> >  	complete(&rs->completion);
> >  	nr = atomic_long_dec_return(&rcu_sr_normal_count);
> > -	WARN_ON_ONCE(nr < 0);
> 
> Why dropping this?
> 
OK, i misread your note about negative, "such as negative returned dec."

--
Uladzislau Rezki

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2026-05-21  5:24 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-19 19:45 [PATCH -next v2 00/11] Candidate patches for the v7.2 merge window Uladzislau Rezki (Sony)
2026-05-19 19:45 ` [PATCH -next v2 01/11] rcutorture: Fully test lazy RCU Uladzislau Rezki (Sony)
2026-05-19 19:45 ` [PATCH -next v2 02/11] torture: Add torture_sched_set_normal() for user-specified nice values Uladzislau Rezki (Sony)
2026-05-19 19:45 ` [PATCH -next v2 03/11] torture: Improve kvm-series.sh header comment Uladzislau Rezki (Sony)
2026-05-19 19:45 ` [PATCH -next v2 04/11] torture: Allow "norm" abbreviation for "normal" Uladzislau Rezki (Sony)
2026-05-19 19:45 ` [PATCH -next v2 05/11] srcu: Fix kerneldoc header comment typo in srcu_down_read_fast() Uladzislau Rezki (Sony)
2026-05-19 19:45 ` [PATCH -next v2 06/11] checkpatch: Undeprecate rcu_read_lock_trace() and rcu_read_unlock_trace() Uladzislau Rezki (Sony)
2026-05-19 19:45 ` [PATCH -next v2 07/11] rcu: Simplify rcu_do_batch() by applying clamp() Uladzislau Rezki (Sony)
2026-05-20 12:26   ` Frederic Weisbecker
2026-05-20 13:54     ` Uladzislau Rezki
2026-05-19 19:45 ` [PATCH -next v2 08/11] rcu: Simplify param_set_next_fqs_jiffies() by applying clamp_val() Uladzislau Rezki (Sony)
2026-05-20 12:31   ` Frederic Weisbecker
2026-05-19 19:45 ` [PATCH -next v2 09/11] rcu: Document rcu_access_pointer() feeding into cmpxchg() Uladzislau Rezki (Sony)
2026-05-20 12:44   ` Frederic Weisbecker
2026-05-19 19:45 ` [PATCH -next v2 10/11] rcu: Latch normal synchronize_rcu() path on flood Uladzislau Rezki (Sony)
2026-05-20 14:43   ` Frederic Weisbecker
2026-05-20 15:16     ` Uladzislau Rezki
2026-05-20 22:28       ` Frederic Weisbecker
2026-05-21  5:23         ` Uladzislau Rezki
2026-05-19 19:45 ` [PATCH -next v2 11/11] rcu-tasks: Fix possible boot-time tests failed for the call_rcu_tasks() Uladzislau Rezki (Sony)

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.