public inbox for rcu@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/11] rcutorture: Add a textbook-style trivial preemptible RCU
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 02/11] kvm-check-branches.sh: Remove in favor of kvm-series.sh Paul E. McKenney
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney

This commit adds a trivial textbook implementation of preemptible RCU
to rcutorture ("torture_type=trivial-preempt"), similar in spirit to the
existing "torture_type=trivial" textbook implementation of non-preemptible
RCU.  Neither trivial RCU implementation has any value for production use,
and are intended only to keep Paul honest in his introductory writings
and presentations.

[ paulmck: Apply kernel test robot feedback. ]
---
 include/linux/sched.h                         |  4 ++
 kernel/rcu/Kconfig.debug                      | 11 ++++
 kernel/rcu/rcu.h                              |  4 ++
 kernel/rcu/rcutorture.c                       | 57 ++++++++++++++++++-
 kernel/rcu/update.c                           | 22 +++++++
 .../rcutorture/configs/rcu/TRIVIAL-PREEMPT    | 12 ++++
 .../configs/rcu/TRIVIAL-PREEMPT.boot          |  3 +
 7 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT.boot

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 074ad4ef3d813..fc2cb6804eabe 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -948,6 +948,10 @@ struct task_struct {
 	struct srcu_ctr __percpu	*trc_reader_scp;
 #endif /* #ifdef CONFIG_TASKS_TRACE_RCU */
 
+#ifdef CONFIG_TRIVIAL_PREEMPT_RCU
+	int				rcu_trivial_preempt_nesting;
+#endif /* #ifdef CONFIG_TRIVIAL_PREEMPT_RCU */
+
 	struct sched_info		sched_info;
 
 	struct list_head		tasks;
diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
index 625d75392647b..e078e988773d6 100644
--- a/kernel/rcu/Kconfig.debug
+++ b/kernel/rcu/Kconfig.debug
@@ -228,4 +228,15 @@ config RCU_DYNTICKS_TORTURE
 
 	  This has no value for production and is only for testing.
 
+config TRIVIAL_PREEMPT_RCU
+	bool "Textbook trivial preemptible RCU in rcutorture"
+	depends on RCU_EXPERT && RCU_TORTURE_TEST
+	default n
+	help
+	  This option enables a textbook preemptible RCU that is
+	  implemented in rcutorture.  Its sole purpose is to validate
+	  code used in books, papers, and presentations.
+
+	  This has no value for production and is only for testing.
+
 endmenu # "RCU Debugging"
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
index dc5d614b372c1..37e7a8a9e375d 100644
--- a/kernel/rcu/rcu.h
+++ b/kernel/rcu/rcu.h
@@ -682,4 +682,8 @@ int rcu_stall_notifier_call_chain(unsigned long val, void *v);
 static inline int rcu_stall_notifier_call_chain(unsigned long val, void *v) { return NOTIFY_DONE; }
 #endif // #else // #if defined(CONFIG_RCU_STALL_COMMON) && defined(CONFIG_RCU_CPU_STALL_NOTIFIER)
 
+#ifdef CONFIG_TRIVIAL_PREEMPT_RCU
+void synchronize_rcu_trivial_preempt(void);
+#endif // #ifdef CONFIG_TRIVIAL_PREEMPT_RCU
+
 #endif /* __LINUX_RCU_H */
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 8a9282a0245cc..3c272413666b2 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1061,6 +1061,61 @@ static struct rcu_torture_ops trivial_ops = {
 	.name		= "trivial"
 };
 
+#ifdef CONFIG_TRIVIAL_PREEMPT_RCU
+
+/*
+ * Definitions for trivial CONFIG_PREEMPT=y torture testing.  This
+ * implementation does not work well with large numbers of tasks or with
+ * long-term preemption.  Either or both get you RCU CPU stall warnings.
+ */
+
+static void rcu_sync_torture_init_trivial_preempt(void)
+{
+	rcu_sync_torture_init();
+	if (WARN_ONCE(onoff_interval || shuffle_interval, "%s: Non-zero onoff_interval (%d) or shuffle_interval (%d) breaks trivial RCU, resetting to zero", __func__, onoff_interval, shuffle_interval)) {
+		onoff_interval = 0;
+		shuffle_interval = 0;
+	}
+}
+
+static int rcu_torture_read_lock_trivial_preempt(void)
+{
+	struct task_struct *t = current;
+
+	WRITE_ONCE(t->rcu_trivial_preempt_nesting, t->rcu_trivial_preempt_nesting + 1);
+	smp_mb();
+	return 0;
+}
+
+static void rcu_torture_read_unlock_trivial_preempt(int idx)
+{
+	struct task_struct *t = current;
+
+	smp_store_release(&t->rcu_trivial_preempt_nesting, t->rcu_trivial_preempt_nesting - 1);
+}
+
+static struct rcu_torture_ops trivial_preempt_ops = {
+	.ttype		= RCU_TRIVIAL_FLAVOR,
+	.init		= rcu_sync_torture_init_trivial_preempt,
+	.readlock	= rcu_torture_read_lock_trivial_preempt,
+	.read_delay	= rcu_read_delay,  // just reuse rcu's version.
+	.readunlock	= rcu_torture_read_unlock_trivial_preempt,
+	.readlock_held	= torture_readlock_not_held,
+	.get_gp_seq	= rcu_no_completed,
+	.sync		= synchronize_rcu_trivial_preempt,
+	.exp_sync	= synchronize_rcu_trivial_preempt,
+	.irq_capable	= 0, // In theory it should be, but let's keep it trivial.
+	.name		= "trivial-preempt"
+};
+
+#define TRIVIAL_PREEMPT_OPS &trivial_preempt_ops,
+
+#else // #ifdef CONFIG_TRIVIAL_PREEMPT_RCU
+
+#define TRIVIAL_PREEMPT_OPS
+
+#endif // #else // #ifdef CONFIG_TRIVIAL_PREEMPT_RCU
+
 #ifdef CONFIG_TASKS_RCU
 
 /*
@@ -4449,7 +4504,7 @@ rcu_torture_init(void)
 	static struct rcu_torture_ops *torture_ops[] = {
 		&rcu_ops, &rcu_busted_ops, &srcu_ops, &srcud_ops, &busted_srcud_ops,
 		TASKS_OPS TASKS_RUDE_OPS TASKS_TRACING_OPS
-		&trivial_ops,
+		&trivial_ops, TRIVIAL_PREEMPT_OPS
 	};
 
 	if (!torture_init_begin(torture_type, verbose))
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index d98a5c38e19c5..b62735a678842 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -538,6 +538,28 @@ long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool do
 EXPORT_SYMBOL_GPL(torture_sched_setaffinity);
 #endif
 
+#if IS_ENABLED(CONFIG_TRIVIAL_PREEMPT_RCU)
+// Trivial and stupid grace-period wait.  Defined here so that lockdep
+// kernels can find tasklist_lock.
+void synchronize_rcu_trivial_preempt(void)
+{
+	struct task_struct *g;
+	struct task_struct *t;
+
+	smp_mb(); // Order prior accesses before grace-period start.
+	rcu_read_lock(); // Protect task list.
+	for_each_process_thread(g, t) {
+		if (t == current)
+			continue;  // Don't deadlock on ourselves!
+		// Order later rcu_read_lock() on other tasks after QS.
+		while (smp_load_acquire(&t->rcu_trivial_preempt_nesting))
+			continue;
+	}
+	rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_trivial_preempt);
+#endif // #if IS_ENABLED(CONFIG_TRIVIAL_PREEMPT_RCU)
+
 int rcu_cpu_stall_notifiers __read_mostly; // !0 = provide stall notifiers (rarely useful)
 EXPORT_SYMBOL_GPL(rcu_cpu_stall_notifiers);
 
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT b/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT
new file mode 100644
index 0000000000000..8230b14bfe680
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT
@@ -0,0 +1,12 @@
+CONFIG_SMP=y
+CONFIG_NR_CPUS=8
+CONFIG_PREEMPT_NONE=n
+CONFIG_PREEMPT_VOLUNTARY=n
+CONFIG_PREEMPT=y
+CONFIG_HZ_PERIODIC=n
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ_FULL=n
+CONFIG_DEBUG_LOCK_ALLOC=n
+CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
+CONFIG_RCU_EXPERT=y
+CONFIG_TRIVIAL_PREEMPT_RCU=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT.boot b/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT.boot
new file mode 100644
index 0000000000000..299cd3a12df6c
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT.boot
@@ -0,0 +1,3 @@
+rcutorture.torture_type=trivial-preempt
+rcutorture.onoff_interval=0
+rcutorture.shuffle_interval=0
-- 
2.40.1


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

* [PATCH 02/11] kvm-check-branches.sh: Remove in favor of kvm-series.sh
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 01/11] rcutorture: Add a textbook-style trivial preemptible RCU Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 03/11] torture: Make hangs more visible in torture.sh output Paul E. McKenney
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney

The kvm-series.sh script is an order-of-magnitude optimization of
kvm-check-branches.sh, so remove the old script.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 .../rcutorture/bin/kvm-check-branches.sh      | 102 ------------------
 1 file changed, 102 deletions(-)
 delete mode 100755 tools/testing/selftests/rcutorture/bin/kvm-check-branches.sh

diff --git a/tools/testing/selftests/rcutorture/bin/kvm-check-branches.sh b/tools/testing/selftests/rcutorture/bin/kvm-check-branches.sh
deleted file mode 100755
index ed0ec7f0927e7..0000000000000
--- a/tools/testing/selftests/rcutorture/bin/kvm-check-branches.sh
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0+
-#
-# Run a group of kvm.sh tests on the specified commits.  This currently
-# unconditionally does three-minute runs on each scenario in CFLIST,
-# taking advantage of all available CPUs and trusting the "make" utility.
-# In the short term, adjustments can be made by editing this script and
-# CFLIST.  If some adjustments appear to have ongoing value, this script
-# might grow some command-line arguments.
-#
-# Usage: kvm-check-branches.sh commit1 commit2..commit3 commit4 ...
-#
-# This script considers its arguments one at a time.  If more elaborate
-# specification of commits is needed, please use "git rev-list" to
-# produce something that this simple script can understand.  The reason
-# for retaining the simplicity is that it allows the user to more easily
-# see which commit came from which branch.
-#
-# This script creates a yyyy.mm.dd-hh.mm.ss-group entry in the "res"
-# directory.  The calls to kvm.sh create the usual entries, but this script
-# moves them under the yyyy.mm.dd-hh.mm.ss-group entry, each in its own
-# directory numbered in run order, that is, "0001", "0002", and so on.
-# For successful runs, the large build artifacts are removed.  Doing this
-# reduces the disk space required by about two orders of magnitude for
-# successful runs.
-#
-# Copyright (C) Facebook, 2020
-#
-# Authors: Paul E. McKenney <paulmck@kernel.org>
-
-if ! git status > /dev/null 2>&1
-then
-	echo '!!!' This script needs to run in a git archive. 1>&2
-	echo '!!!' Giving up. 1>&2
-	exit 1
-fi
-
-# Remember where we started so that we can get back at the end.
-curcommit="`git status | head -1 | awk '{ print $NF }'`"
-
-nfail=0
-ntry=0
-resdir="tools/testing/selftests/rcutorture/res"
-ds="`date +%Y.%m.%d-%H.%M.%S`-group"
-if ! test -e $resdir
-then
-	mkdir $resdir || :
-fi
-mkdir $resdir/$ds
-echo Results directory: $resdir/$ds
-
-RCUTORTURE="`pwd`/tools/testing/selftests/rcutorture"; export RCUTORTURE
-PATH=${RCUTORTURE}/bin:$PATH; export PATH
-. functions.sh
-echo Using all `identify_qemu_vcpus` CPUs.
-
-# Each pass through this loop does one command-line argument.
-for gitbr in $@
-do
-	echo ' --- git branch ' $gitbr
-
-	# Each pass through this loop tests one commit.
-	for i in `git rev-list "$gitbr"`
-	do
-		ntry=`expr $ntry + 1`
-		idir=`awk -v ntry="$ntry" 'END { printf "%04d", ntry; }' < /dev/null`
-		echo ' --- commit ' $i from branch $gitbr
-		date
-		mkdir $resdir/$ds/$idir
-		echo $gitbr > $resdir/$ds/$idir/gitbr
-		echo $i >> $resdir/$ds/$idir/gitbr
-
-		# Test the specified commit.
-		git checkout $i > $resdir/$ds/$idir/git-checkout.out 2>&1
-		echo git checkout return code: $? "(Commit $ntry: $i)"
-		kvm.sh --allcpus --duration 3 --trust-make --datestamp "$ds/$idir" > $resdir/$ds/$idir/kvm.sh.out 2>&1
-		ret=$?
-		echo kvm.sh return code $ret for commit $i from branch $gitbr
-		echo Run results: $resdir/$ds/$idir
-		if test "$ret" -ne 0
-		then
-			# Failure, so leave all evidence intact.
-			nfail=`expr $nfail + 1`
-		else
-			# Success, so remove large files to save about 1GB.
-			( cd $resdir/$ds/$idir/$rrd; rm -f */vmlinux */bzImage */System.map */Module.symvers )
-		fi
-	done
-done
-date
-
-# Go back to the original commit.
-git checkout "$curcommit"
-
-if test $nfail -ne 0
-then
-	echo '!!! ' $nfail failures in $ntry 'runs!!!'
-	exit 1
-else
-	echo No failures in $ntry runs.
-	exit 0
-fi
-- 
2.40.1


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

* [PATCH 03/11] torture: Make hangs more visible in torture.sh output
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 01/11] rcutorture: Add a textbook-style trivial preemptible RCU Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 02/11] kvm-check-branches.sh: Remove in favor of kvm-series.sh Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 04/11] rcutorture: Adjust scenarios for default lazy preemption Paul E. McKenney
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney

This commit labels "QEMU killed" lines so that they will be picked up
by torture.sh processing.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 tools/testing/selftests/rcutorture/bin/kvm-recheck.sh   | 2 +-
 tools/testing/selftests/rcutorture/bin/parse-console.sh | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
index de65d77b47ff7..4791774b8485a 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
@@ -49,7 +49,7 @@ do
 		then
 			if test -f "$i/qemu-retval" && test "`cat $i/qemu-retval`" -eq 137
 			then
-				echo QEMU killed
+				echo "Summary: Potential hang (QEMU killed)"
 			fi
 			configcheck.sh $i/.config $i/ConfigFragment > $i/ConfigFragment.diags 2>&1
 			if grep -q '^CONFIG_KCSAN=y$' $i/ConfigFragment.input
diff --git a/tools/testing/selftests/rcutorture/bin/parse-console.sh b/tools/testing/selftests/rcutorture/bin/parse-console.sh
index 21e6ba3615f6a..be1e943ca4d51 100755
--- a/tools/testing/selftests/rcutorture/bin/parse-console.sh
+++ b/tools/testing/selftests/rcutorture/bin/parse-console.sh
@@ -113,7 +113,6 @@ then
 		then
 			print_warning $title `cat $T.seq`
 		fi
-		exit 2
 	fi
 fi | tee -a $file.diags
 
-- 
2.40.1


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

* [PATCH 04/11] rcutorture: Adjust scenarios for default lazy preemption
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
                   ` (2 preceding siblings ...)
  2026-03-03 23:50 ` [PATCH 03/11] torture: Make hangs more visible in torture.sh output Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 05/11] torture: Print informative message for test without recheck file Paul E. McKenney
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney

Currently, most of the rcutorture scenarios do not explicitly set the
CONFIG_PREEMPT_LAZY Kconfig option one way or the other.  This can
result int "improperly set" diagnostics from kvm.sh, which indicate
that the scenario in question isn't testing what it is supposed to test,
which can result in missed bugs.   This commit therefore explicitly sets
CONFIG_PREEMPT_LAZY as needed.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 tools/testing/selftests/rcutorture/configs/rcu/TINY01 | 1 +
 tools/testing/selftests/rcutorture/configs/rcu/TREE04 | 2 ++
 tools/testing/selftests/rcutorture/configs/rcu/TREE05 | 1 +
 tools/testing/selftests/rcutorture/configs/rcu/TREE06 | 2 ++
 tools/testing/selftests/rcutorture/configs/rcu/TREE10 | 1 +
 5 files changed, 7 insertions(+)

diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TINY01 b/tools/testing/selftests/rcutorture/configs/rcu/TINY01
index 0953c52fcfd76..bd5ed7b0da5f0 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TINY01
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TINY01
@@ -3,6 +3,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_PREEMPT_VOLUNTARY=n
 CONFIG_PREEMPT=n
 CONFIG_PREEMPT_DYNAMIC=n
+CONFIG_PREEMPT_LAZY=n
 #CHECK#CONFIG_TINY_RCU=y
 CONFIG_HZ_PERIODIC=n
 CONFIG_NO_HZ_IDLE=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE04 b/tools/testing/selftests/rcutorture/configs/rcu/TREE04
index 67caf4276bb01..f49fda1c88811 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE04
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE04
@@ -4,7 +4,9 @@ CONFIG_PREEMPT_NONE=n
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_PREEMPT=n
 CONFIG_PREEMPT_DYNAMIC=n
+CONFIG_PREEMPT_LAZY=n
 #CHECK#CONFIG_TREE_RCU=y
+#CHECK#CONFIG_PREEMPT_RCU=n
 CONFIG_HZ_PERIODIC=n
 CONFIG_NO_HZ_IDLE=n
 CONFIG_NO_HZ_FULL=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE05 b/tools/testing/selftests/rcutorture/configs/rcu/TREE05
index 9f48c73709ec3..0513aa33c32c4 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE05
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE05
@@ -3,6 +3,7 @@ CONFIG_NR_CPUS=8
 CONFIG_PREEMPT_NONE=y
 CONFIG_PREEMPT_VOLUNTARY=n
 CONFIG_PREEMPT=n
+CONFIG_PREEMPT_LAZY=n
 #CHECK#CONFIG_TREE_RCU=y
 CONFIG_HZ_PERIODIC=n
 CONFIG_NO_HZ_IDLE=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE06 b/tools/testing/selftests/rcutorture/configs/rcu/TREE06
index db27651de04b8..bfd88c46dbd73 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE06
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE06
@@ -3,7 +3,9 @@ CONFIG_NR_CPUS=8
 CONFIG_PREEMPT_NONE=y
 CONFIG_PREEMPT_VOLUNTARY=n
 CONFIG_PREEMPT=n
+CONFIG_PREEMPT_LAZY=n
 #CHECK#CONFIG_TREE_RCU=y
+#CHECK#CONFIG_PREEMPT_RCU=n
 CONFIG_HZ_PERIODIC=n
 CONFIG_NO_HZ_IDLE=y
 CONFIG_NO_HZ_FULL=n
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE10 b/tools/testing/selftests/rcutorture/configs/rcu/TREE10
index 420632b030dc4..b2ce37861e71a 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE10
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE10
@@ -6,6 +6,7 @@ CONFIG_PREEMPT_VOLUNTARY=n
 CONFIG_PREEMPT=n
 CONFIG_PREEMPT_DYNAMIC=n
 #CHECK#CONFIG_TREE_RCU=y
+CONFIG_PREEMPT_RCU=n
 CONFIG_HZ_PERIODIC=n
 CONFIG_NO_HZ_IDLE=y
 CONFIG_NO_HZ_FULL=n
-- 
2.40.1


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

* [PATCH 0/11] rcu: Miscellaneous patches for v7.1
@ 2026-03-03 23:50 Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 01/11] rcutorture: Add a textbook-style trivial preemptible RCU Paul E. McKenney
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt

Hello!

This is a series of miscellaneous patches for v7.1.  7/11 and 8/11
were generated with the assistance of an LLM named Claude.  The prompt
directed Claude at existing Linux-kernel code, and I inspected the output
to verify that the expected changes were made.  I also undertook the
usual testing.

The patches themselves are as follows:

1.	Add a textbook-style trivial preemptible RCU.

2.	kvm-check-branches.sh: Remove in favor of kvm-series.sh.

3.	Make hangs more visible in torture.sh output.

4.	Adjust scenarios for default lazy preemption.

5.	Print informative message for test without recheck file.

6.	Fix numeric "test" comparison in srcu_lockdep.sh.

7.	Ditch ref_scale_shutdown in favor of torture_shutdown_init().

8.	Ditch rcu_scale_shutdown in favor of torture_shutdown_init().

9.	Fix SRCU read flavor macro comments.

10.	Fix s/they disables/they disable/ typo in srcu_read_unlock_fast().

11.	Document that RCU Tasks Trace grace periods now imply RCU grace
	periods.

						Thanx, Paul

------------------------------------------------------------------------

 b/Documentation/RCU/Design/Requirements/Requirements.rst               |    7 
 b/include/linux/rcupdate.h                                             |    9 
 b/include/linux/sched.h                                                |    4 
 b/include/linux/srcu.h                                                 |    4 
 b/include/linux/srcutree.h                                             |    2 
 b/kernel/rcu/Kconfig.debug                                             |   11 +
 b/kernel/rcu/rcu.h                                                     |    4 
 b/kernel/rcu/rcuscale.c                                                |   78 ++-----
 b/kernel/rcu/rcutorture.c                                              |   57 +++++
 b/kernel/rcu/refscale.c                                                |   51 +----
 b/kernel/rcu/update.c                                                  |   22 ++
 b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh                |    2 
 b/tools/testing/selftests/rcutorture/bin/parse-console.sh              |    1 
 b/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh               |    6 
 b/tools/testing/selftests/rcutorture/configs/rcu/TINY01                |    1 
 b/tools/testing/selftests/rcutorture/configs/rcu/TREE04                |    2 
 b/tools/testing/selftests/rcutorture/configs/rcu/TREE05                |    1 
 b/tools/testing/selftests/rcutorture/configs/rcu/TREE06                |    2 
 b/tools/testing/selftests/rcutorture/configs/rcu/TREE10                |    1 
 b/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT       |   12 +
 b/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT.boot  |    3 
 b/tools/testing/selftests/rcutorture/configs/rcuscale/ver_functions.sh |    2 
 b/tools/testing/selftests/rcutorture/configs/refscale/ver_functions.sh |    2 
 tools/testing/selftests/rcutorture/bin/kvm-check-branches.sh           |  102 ----------
 tools/testing/selftests/rcutorture/bin/kvm-recheck.sh                  |    7 
 25 files changed, 179 insertions(+), 214 deletions(-)

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

* [PATCH 05/11] torture: Print informative message for test without recheck file
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
                   ` (3 preceding siblings ...)
  2026-03-03 23:50 ` [PATCH 04/11] rcutorture: Adjust scenarios for default lazy preemption Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 06/11] rcutorture: Fix numeric "test" comparison in srcu_lockdep.sh Paul E. McKenney
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney

If a type of torture test lacks a recheck file, a bash diagnostic is
printed, which looks like a torture-test bug.  This commit gets rid of
this false positive by explicitly checking for the file, invoking it if
it exists, otherwise printing an informative non-diagnostic message.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 tools/testing/selftests/rcutorture/bin/kvm-recheck.sh | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
index 4791774b8485a..63bbbdd5f4ef3 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
@@ -39,7 +39,12 @@ do
 		X*)
 			;;
 		*)
-			kvm-recheck-${TORTURE_SUITE}.sh $i
+			if test -f tools/testing/selftests/rcutorture/bin/kvm-recheck-${TORTURE_SUITE}.sh
+			then
+				kvm-recheck-${TORTURE_SUITE}.sh $i
+			else
+				echo No kvm-recheck-${TORTURE_SUITE}.sh, so no ${TORTURE_SUITE}-specific analysis.
+			fi
 		esac
 		if test -f "$i/qemu-retval" && test "`cat $i/qemu-retval`" -ne 0 && test "`cat $i/qemu-retval`" -ne 137
 		then
-- 
2.40.1


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

* [PATCH 06/11] rcutorture: Fix numeric "test" comparison in srcu_lockdep.sh
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
                   ` (4 preceding siblings ...)
  2026-03-03 23:50 ` [PATCH 05/11] torture: Print informative message for test without recheck file Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 07/11] refscale: Ditch ref_scale_shutdown in favor of torture_shutdown_init() Paul E. McKenney
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney

This commit switches from "-eq" to "=" to handle the non-numeric
comparisons in srcu_lockdep.sh.  While in the area, adjust SRCU flavor
to improve coverage.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh b/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh
index 208be7d09a612..4e98c697def48 100755
--- a/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh
+++ b/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh
@@ -50,7 +50,7 @@ do
 		do
 			err=
 			val=$((d*1000+t*10+c))
-			tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 5s --configs "SRCU-P" --kconfig "CONFIG_FORCE_NEED_SRCU_NMI_SAFE=y" --bootargs "rcutorture.test_srcu_lockdep=$val rcutorture.reader_flavor=0x2" --trust-make --datestamp "$ds/$val" > "$T/kvm.sh.out" 2>&1
+			tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 5s --configs "SRCU-P" --kconfig "CONFIG_FORCE_NEED_SRCU_NMI_SAFE=y" --bootargs "rcutorture.test_srcu_lockdep=$val rcutorture.reader_flavor=0x4" --trust-make --datestamp "$ds/$val" > "$T/kvm.sh.out" 2>&1
 			ret=$?
 			mv "$T/kvm.sh.out" "$RCUTORTURE/res/$ds/$val"
 			if ! grep -q '^CONFIG_PROVE_LOCKING=y' .config
@@ -92,12 +92,12 @@ do
 		nerrs=$((nerrs+1))
 		err=1
 	fi
-	if test "$val" -eq 0xf && test "$ret" -eq 0
+	if test "$val" = 0xf && test "$ret" -eq 0
 	then
 		err=1
 		echo -n Unexpected success for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
 	fi
-	if test "$val" -eq 0x1 && test "$ret" -ne 0
+	if test "$val" = 0x1 && test "$ret" -ne 0
 	then
 		err=1
 		echo -n Unexpected failure for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err"
-- 
2.40.1


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

* [PATCH 07/11] refscale: Ditch ref_scale_shutdown in favor of torture_shutdown_init()
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
                   ` (5 preceding siblings ...)
  2026-03-03 23:50 ` [PATCH 06/11] rcutorture: Fix numeric "test" comparison in srcu_lockdep.sh Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 08/11] rcuscale: Ditch rcu_scale_shutdown " Paul E. McKenney
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney

The torture_shutdown_init() function spawns a shutdown kthread in
a manner very similar to that implemented by ref_scale_shutdown().
This commit therefore re-implements ref_scale_shutdown in terms of
torture_shutdown_init().

The initial draft of this patch was generated by version 2.1.16 of the
Claude AI/LLM, but trained and configured for use by my employer, and
prompted to refer to Linux-kernel source code.  This initial draft failed
to provide a forward reference to ref_scale_cleanup(), passed zero to
torture_shutdown_init() for an unwelcome insta-shutdown, and failed to
pass the kvm.sh --duration argument in as a refscale module parameter.
On the other hand, it did catch the need to NULL main_task on the
post-test self-shutdown code path, which I might well have forgotten
to do.

This version of the patch fixes those problems, and in fact very little
of the initial draft remains.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>

[outline more of development process]

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 kernel/rcu/refscale.c                         | 51 +++++--------------
 .../configs/refscale/ver_functions.sh         |  2 +-
 2 files changed, 15 insertions(+), 38 deletions(-)

diff --git a/kernel/rcu/refscale.c b/kernel/rcu/refscale.c
index c158b6a947cde..a2d9d75d88a10 100644
--- a/kernel/rcu/refscale.c
+++ b/kernel/rcu/refscale.c
@@ -92,15 +92,9 @@ torture_param(int, nreaders, -1, "Number of readers, -1 for 75% of CPUs.");
 torture_param(int, nruns, 30, "Number of experiments to run.");
 // Reader delay in nanoseconds, 0 for no delay.
 torture_param(int, readdelay, 0, "Read-side delay in nanoseconds.");
-
-#ifdef MODULE
-# define REFSCALE_SHUTDOWN 0
-#else
-# define REFSCALE_SHUTDOWN 1
-#endif
-
-torture_param(bool, shutdown, REFSCALE_SHUTDOWN,
-	      "Shutdown at end of scalability tests.");
+// Maximum shutdown delay in seconds, or zero for no shutdown.
+torture_param(int, shutdown_secs, !IS_MODULE(CONFIG_REPRO_TEST) * 300,
+	      "Shutdown at end of scalability tests or at specified timeout (s).");
 
 struct reader_task {
 	struct task_struct *task;
@@ -109,12 +103,8 @@ struct reader_task {
 	u64 last_duration_ns;
 };
 
-static struct task_struct *shutdown_task;
-static wait_queue_head_t shutdown_wq;
-
 static struct task_struct *main_task;
 static wait_queue_head_t main_wq;
-static int shutdown_start;
 
 static struct reader_task *reader_tasks;
 
@@ -1357,6 +1347,8 @@ static u64 process_durations(int n)
 	return sum;
 }
 
+static void ref_scale_cleanup(void);
+
 // The main_func is the main orchestrator, it performs a bunch of
 // experiments.  For every experiment, it orders all the readers
 // involved to start and waits for them to finish the experiment. It
@@ -1443,9 +1435,10 @@ static int main_func(void *arg)
 
 oom_exit:
 	// This will shutdown everything including us.
-	if (shutdown) {
-		shutdown_start = 1;
-		wake_up(&shutdown_wq);
+	if (shutdown_secs) {
+		main_task = NULL;  // Avoid self-kill deadlock.
+		ref_scale_cleanup();
+		kernel_power_off();
 	}
 
 	// Wait for torture to stop us
@@ -1463,8 +1456,8 @@ static void
 ref_scale_print_module_parms(const struct ref_scale_ops *cur_ops, const char *tag)
 {
 	pr_alert("%s" SCALE_FLAG
-		 "--- %s:  verbose=%d verbose_batched=%d shutdown=%d holdoff=%d lookup_instances=%ld loops=%d nreaders=%d nruns=%d readdelay=%d\n", scale_type, tag,
-		 verbose, verbose_batched, shutdown, holdoff, lookup_instances, loops, nreaders, nruns, readdelay);
+		 "--- %s:  verbose=%d verbose_batched=%d shutdown_secs=%d holdoff=%d lookup_instances=%ld loops=%d nreaders=%d nruns=%d readdelay=%d\n", scale_type, tag,
+		 verbose, verbose_batched, shutdown_secs, holdoff, lookup_instances, loops, nreaders, nruns, readdelay);
 }
 
 static void
@@ -1497,19 +1490,6 @@ ref_scale_cleanup(void)
 	torture_cleanup_end();
 }
 
-// Shutdown kthread.  Just waits to be awakened, then shuts down system.
-static int
-ref_scale_shutdown(void *arg)
-{
-	wait_event_idle(shutdown_wq, shutdown_start);
-
-	smp_mb(); // Wake before output.
-	ref_scale_cleanup();
-	kernel_power_off();
-
-	return -EINVAL;
-}
-
 static int __init
 ref_scale_init(void)
 {
@@ -1553,13 +1533,10 @@ ref_scale_init(void)
 	ref_scale_print_module_parms(cur_ops, "Start of test");
 
 	// Shutdown task
-	if (shutdown) {
-		init_waitqueue_head(&shutdown_wq);
-		firsterr = torture_create_kthread(ref_scale_shutdown, NULL,
-						  shutdown_task);
+	if (shutdown_secs) {
+		firsterr = torture_shutdown_init(shutdown_secs, ref_scale_cleanup);
 		if (torture_init_error(firsterr))
 			goto unwind;
-		schedule_timeout_uninterruptible(1);
 	}
 
 	// Reader tasks (default to ~75% of online CPUs).
@@ -1604,7 +1581,7 @@ ref_scale_init(void)
 unwind:
 	torture_init_end();
 	ref_scale_cleanup();
-	if (shutdown) {
+	if (shutdown_secs) {
 		WARN_ON(!IS_MODULE(CONFIG_RCU_REF_SCALE_TEST));
 		kernel_power_off();
 	}
diff --git a/tools/testing/selftests/rcutorture/configs/refscale/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/refscale/ver_functions.sh
index 7484656276012..219fac070af28 100644
--- a/tools/testing/selftests/rcutorture/configs/refscale/ver_functions.sh
+++ b/tools/testing/selftests/rcutorture/configs/refscale/ver_functions.sh
@@ -11,7 +11,7 @@
 #
 # Adds per-version torture-module parameters to kernels supporting them.
 per_version_boot_params () {
-	echo	refscale.shutdown=1 \
+	echo	refscale.shutdown_secs=$3 \
 		refscale.verbose=0 \
 		$1
 }
-- 
2.40.1


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

* [PATCH 08/11] rcuscale: Ditch rcu_scale_shutdown in favor of torture_shutdown_init()
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
                   ` (6 preceding siblings ...)
  2026-03-03 23:50 ` [PATCH 07/11] refscale: Ditch ref_scale_shutdown in favor of torture_shutdown_init() Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 09/11] srcu: Fix SRCU read flavor macro comments Paul E. McKenney
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney

The torture_shutdown_init() function spawns a shutdown kthread in
a manner very similar to that implemented by rcu_scale_shutdown().
This commit therefore re-implements rcu_scale_shutdown() in terms of
torture_shutdown_init().

This patch was generated by Claude given as input the patch making the
same transformation of ref_scale_shutdown().

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 kernel/rcu/rcuscale.c                         | 78 +++++--------------
 .../configs/rcuscale/ver_functions.sh         |  2 +-
 2 files changed, 22 insertions(+), 58 deletions(-)

diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
index 4ac2b134a9833..ac0b1c6b7dae2 100644
--- a/kernel/rcu/rcuscale.c
+++ b/kernel/rcu/rcuscale.c
@@ -79,12 +79,6 @@ MODULE_AUTHOR("Paul E. McKenney <paulmck@linux.ibm.com>");
  * test-end checks, and the pair of calls through pointers.
  */
 
-#ifdef MODULE
-# define RCUSCALE_SHUTDOWN 0
-#else
-# define RCUSCALE_SHUTDOWN 1
-#endif
-
 torture_param(bool, gp_async, false, "Use asynchronous GP wait primitives");
 torture_param(int, gp_async_max, 1000, "Max # outstanding waits per writer");
 torture_param(bool, gp_exp, false, "Use expedited GP wait primitives");
@@ -92,8 +86,8 @@ torture_param(int, holdoff, 10, "Holdoff time before test start (s)");
 torture_param(int, minruntime, 0, "Minimum run time (s)");
 torture_param(int, nreaders, -1, "Number of RCU reader threads");
 torture_param(int, nwriters, -1, "Number of RCU updater threads");
-torture_param(bool, shutdown, RCUSCALE_SHUTDOWN,
-	      "Shutdown at end of scalability tests.");
+torture_param(int, shutdown_secs, !IS_MODULE(CONFIG_RCU_SCALE_TEST) * 300,
+	      "Shutdown at end of scalability tests or at specified timeout (s).");
 torture_param(int, verbose, 1, "Enable verbose debugging printk()s");
 torture_param(int, writer_holdoff, 0, "Holdoff (us) between GPs, zero to disable");
 torture_param(int, writer_holdoff_jiffies, 0, "Holdoff (jiffies) between GPs, zero to disable");
@@ -123,7 +117,6 @@ static int nrealreaders;
 static int nrealwriters;
 static struct task_struct **writer_tasks;
 static struct task_struct **reader_tasks;
-static struct task_struct *shutdown_task;
 
 static u64 **writer_durations;
 static bool *writer_done;
@@ -132,7 +125,6 @@ static int *writer_n_durations;
 static atomic_t n_rcu_scale_reader_started;
 static atomic_t n_rcu_scale_writer_started;
 static atomic_t n_rcu_scale_writer_finished;
-static wait_queue_head_t shutdown_wq;
 static u64 t_rcu_scale_writer_started;
 static u64 t_rcu_scale_writer_finished;
 static unsigned long b_rcu_gp_test_started;
@@ -519,6 +511,8 @@ static void rcu_scale_async_cb(struct rcu_head *rhp)
 	rcu_scale_free(wmbp);
 }
 
+static void rcu_scale_cleanup(void);
+
 /*
  * RCU scale writer kthread.  Repeatedly does a grace period.
  */
@@ -622,9 +616,11 @@ rcu_scale_writer(void *arg)
 					b_rcu_gp_test_finished =
 						cur_ops->get_gp_seq();
 				}
-				if (shutdown) {
+				if (shutdown_secs) {
+					writer_tasks[me] = NULL;
 					smp_mb(); /* Assign before wake. */
-					wake_up(&shutdown_wq);
+					rcu_scale_cleanup();
+					kernel_power_off();
 				}
 			}
 		}
@@ -668,8 +664,8 @@ static void
 rcu_scale_print_module_parms(struct rcu_scale_ops *cur_ops, const char *tag)
 {
 	pr_alert("%s" SCALE_FLAG
-		 "--- %s: gp_async=%d gp_async_max=%d gp_exp=%d holdoff=%d minruntime=%d nreaders=%d nwriters=%d writer_holdoff=%d writer_holdoff_jiffies=%d verbose=%d shutdown=%d\n",
-		 scale_type, tag, gp_async, gp_async_max, gp_exp, holdoff, minruntime, nrealreaders, nrealwriters, writer_holdoff, writer_holdoff_jiffies, verbose, shutdown);
+		 "--- %s: gp_async=%d gp_async_max=%d gp_exp=%d holdoff=%d minruntime=%d nreaders=%d nwriters=%d writer_holdoff=%d writer_holdoff_jiffies=%d verbose=%d shutdown_secs=%d\n",
+		 scale_type, tag, gp_async, gp_async_max, gp_exp, holdoff, minruntime, nrealreaders, nrealwriters, writer_holdoff, writer_holdoff_jiffies, verbose, shutdown_secs);
 }
 
 /*
@@ -722,6 +718,8 @@ static void kfree_call_rcu(struct rcu_head *rh)
 	kfree(obj);
 }
 
+static void kfree_scale_cleanup(void);
+
 static int
 kfree_scale_thread(void *arg)
 {
@@ -791,9 +789,11 @@ kfree_scale_thread(void *arg)
 		       rcuscale_seq_diff(b_rcu_gp_test_finished, b_rcu_gp_test_started),
 		       PAGES_TO_MB(mem_begin - mem_during));
 
-		if (shutdown) {
+		if (shutdown_secs) {
+			kfree_reader_tasks[me] = NULL;
 			smp_mb(); /* Assign before wake. */
-			wake_up(&shutdown_wq);
+			kfree_scale_cleanup();
+			kernel_power_off();
 		}
 	}
 
@@ -820,22 +820,6 @@ kfree_scale_cleanup(void)
 	torture_cleanup_end();
 }
 
-/*
- * shutdown kthread.  Just waits to be awakened, then shuts down system.
- */
-static int
-kfree_scale_shutdown(void *arg)
-{
-	wait_event_idle(shutdown_wq,
-			atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
-
-	smp_mb(); /* Wake before output. */
-
-	kfree_scale_cleanup();
-	kernel_power_off();
-	return -EINVAL;
-}
-
 // Used if doing RCU-kfree'ing via call_rcu().
 static unsigned long jiffies_at_lazy_cb;
 static struct rcu_head lazy_test1_rh;
@@ -895,13 +879,10 @@ kfree_scale_init(void)
 
 	kfree_nrealthreads = compute_real(kfree_nthreads);
 	/* Start up the kthreads. */
-	if (shutdown) {
-		init_waitqueue_head(&shutdown_wq);
-		firsterr = torture_create_kthread(kfree_scale_shutdown, NULL,
-						  shutdown_task);
+	if (shutdown_secs) {
+		firsterr = torture_shutdown_init(shutdown_secs, kfree_scale_cleanup);
 		if (torture_init_error(firsterr))
 			goto unwind;
-		schedule_timeout_uninterruptible(1);
 	}
 
 	pr_alert("kfree object size=%zu, kfree_by_call_rcu=%d\n",
@@ -1058,20 +1039,6 @@ rcu_scale_cleanup(void)
 	torture_cleanup_end();
 }
 
-/*
- * RCU scalability shutdown kthread.  Just waits to be awakened, then shuts
- * down system.
- */
-static int
-rcu_scale_shutdown(void *arg)
-{
-	wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
-	smp_mb(); /* Wake before output. */
-	rcu_scale_cleanup();
-	kernel_power_off();
-	return -EINVAL;
-}
-
 static int __init
 rcu_scale_init(void)
 {
@@ -1121,13 +1088,10 @@ rcu_scale_init(void)
 
 	/* Start up the kthreads. */
 
-	if (shutdown) {
-		init_waitqueue_head(&shutdown_wq);
-		firsterr = torture_create_kthread(rcu_scale_shutdown, NULL,
-						  shutdown_task);
+	if (shutdown_secs) {
+		firsterr = torture_shutdown_init(shutdown_secs, rcu_scale_cleanup);
 		if (torture_init_error(firsterr))
 			goto unwind;
-		schedule_timeout_uninterruptible(1);
 	}
 	reader_tasks = kzalloc_objs(reader_tasks[0], nrealreaders);
 	if (reader_tasks == NULL) {
@@ -1201,7 +1165,7 @@ rcu_scale_init(void)
 unwind:
 	torture_init_end();
 	rcu_scale_cleanup();
-	if (shutdown) {
+	if (shutdown_secs) {
 		WARN_ON(!IS_MODULE(CONFIG_RCU_SCALE_TEST));
 		kernel_power_off();
 	}
diff --git a/tools/testing/selftests/rcutorture/configs/rcuscale/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/rcuscale/ver_functions.sh
index 28070b43f0171..b78ddc243d891 100644
--- a/tools/testing/selftests/rcutorture/configs/rcuscale/ver_functions.sh
+++ b/tools/testing/selftests/rcutorture/configs/rcuscale/ver_functions.sh
@@ -11,7 +11,7 @@
 #
 # Adds per-version torture-module parameters to kernels supporting them.
 per_version_boot_params () {
-	echo	rcuscale.shutdown=1 \
+	echo	rcuscale.shutdown_secs=$3 \
 		rcuscale.verbose=0 \
 		$1
 }
-- 
2.40.1


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

* [PATCH 09/11] srcu: Fix SRCU read flavor macro comments
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
                   ` (7 preceding siblings ...)
  2026-03-03 23:50 ` [PATCH 08/11] rcuscale: Ditch rcu_scale_shutdown " Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 10/11] srcu: Fix s/they disables/they disable/ typo in srcu_read_unlock_fast() Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 11/11] rcu-tasks: Document that RCU Tasks Trace grace periods now imply RCU grace periods Paul E. McKenney
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney

The SRCU_READ_FLAVOR_FAST and SRCU_READ_FLAVOR_FAST_UPDOWN comments
need repair.  The former fails to not that SRCU-fast can be used in NMI
handlers, and the latter says that it goes with srcu_read_lock_fast()
when it really goes with srcu_read_lock_fast_updown().  This commit
therefore fixes both comments.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 include/linux/srcu.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index bb44a0bd76968..81b1938512d5d 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -69,8 +69,8 @@ int init_srcu_struct_fast_updown(struct srcu_struct *ssp);
 #define SRCU_READ_FLAVOR_NORMAL		0x1		// srcu_read_lock().
 #define SRCU_READ_FLAVOR_NMI		0x2		// srcu_read_lock_nmisafe().
 //					0x4		// SRCU-lite is no longer with us.
-#define SRCU_READ_FLAVOR_FAST		0x4		// srcu_read_lock_fast().
-#define SRCU_READ_FLAVOR_FAST_UPDOWN	0x8		// srcu_read_lock_fast().
+#define SRCU_READ_FLAVOR_FAST		0x4		// srcu_read_lock_fast(), also NMI-safe.
+#define SRCU_READ_FLAVOR_FAST_UPDOWN	0x8		// srcu_read_lock_fast_updown().
 #define SRCU_READ_FLAVOR_ALL		(SRCU_READ_FLAVOR_NORMAL | SRCU_READ_FLAVOR_NMI | \
 					 SRCU_READ_FLAVOR_FAST | SRCU_READ_FLAVOR_FAST_UPDOWN)
 						// All of the above.
-- 
2.40.1


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

* [PATCH 10/11] srcu: Fix s/they disables/they disable/ typo in srcu_read_unlock_fast()
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
                   ` (8 preceding siblings ...)
  2026-03-03 23:50 ` [PATCH 09/11] srcu: Fix SRCU read flavor macro comments Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  2026-03-03 23:50 ` [PATCH 11/11] rcu-tasks: Document that RCU Tasks Trace grace periods now imply RCU grace periods Paul E. McKenney
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu; +Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney,
	Mathieu Desnoyers

Typo fix in srcu_read_unlock_fast() header comment.

Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
 include/linux/srcutree.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h
index 958cb7ef41cbb..ad783d4dd3677 100644
--- a/include/linux/srcutree.h
+++ b/include/linux/srcutree.h
@@ -259,7 +259,7 @@ static inline struct srcu_ctr __percpu *__srcu_ctr_to_ptr(struct srcu_struct *ss
  * srcu_read_unlock_fast().
  *
  * Note that both this_cpu_inc() and atomic_long_inc() are RCU read-side
- * critical sections either because they disables interrupts, because
+ * critical sections either because they disable interrupts, because
  * they are a single instruction, or because they are read-modify-write
  * atomic operations, depending on the whims of the architecture.
  * This matters because the SRCU-fast grace-period mechanism uses either
-- 
2.40.1


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

* [PATCH 11/11] rcu-tasks: Document that RCU Tasks Trace grace periods now imply RCU grace periods
  2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
                   ` (9 preceding siblings ...)
  2026-03-03 23:50 ` [PATCH 10/11] srcu: Fix s/they disables/they disable/ typo in srcu_read_unlock_fast() Paul E. McKenney
@ 2026-03-03 23:50 ` Paul E. McKenney
  10 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-03-03 23:50 UTC (permalink / raw)
  To: rcu
  Cc: linux-kernel, kernel-team, rostedt, Paul E. McKenney,
	Alexei Starovoitov

Now that RCU Tasks Trace is implemented in terms of SRCU-fast, the fact
that each SRCU-fast grace period implies at least two RCU grace periods
in turn means that each RCU Tasks Trace grace period implies at least
two grace periods.  This commit therefore updates the documentation
accordingly.

Reported-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
 Documentation/RCU/Design/Requirements/Requirements.rst | 7 +++++++
 include/linux/rcupdate.h                               | 9 +++------
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst
index b5cdbba3ec2e7..4d886e7c7a956 100644
--- a/Documentation/RCU/Design/Requirements/Requirements.rst
+++ b/Documentation/RCU/Design/Requirements/Requirements.rst
@@ -2787,6 +2787,13 @@ which avoids the read-side memory barriers, at least for architectures
 that apply noinstr to kernel entry/exit code (or that build with
 ``CONFIG_TASKS_TRACE_RCU_NO_MB=y``.
 
+Now that the implementation is based on SRCU-fast, a call
+to synchronize_rcu_tasks_trace() implies at least one call to
+synchronize_rcu(), that is, every Tasks Trace RCU grace period contains
+at least one plain vanilla RCU grace period.  Should there ever
+be a synchronize_rcu_tasks_trace_expedited(), this guarantee would
+*not* necessarily apply to this hypothetical API member.
+
 The tasks-trace-RCU API is also reasonably compact,
 consisting of rcu_read_lock_trace(), rcu_read_unlock_trace(),
 rcu_read_lock_trace_held(), call_rcu_tasks_trace(),
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 04f3f86a41450..18a85c30fd4f3 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -208,12 +208,9 @@ static inline void exit_tasks_rcu_finish(void) { }
 /**
  * rcu_trace_implies_rcu_gp - does an RCU Tasks Trace grace period imply an RCU grace period?
  *
- * As an accident of implementation, an RCU Tasks Trace grace period also
- * acts as an RCU grace period.  However, this could change at any time.
- * Code relying on this accident must call this function to verify that
- * this accident is still happening.
- *
- * You have been warned!
+ * Now that RCU Tasks Trace is implemented in terms of SRCU-fast, a
+ * call to synchronize_rcu_tasks_trace() is guaranteed to imply at least
+ * one call to synchronize_rcu().
  */
 static inline bool rcu_trace_implies_rcu_gp(void) { return true; }
 
-- 
2.40.1


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

end of thread, other threads:[~2026-03-03 23:50 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-03 23:50 [PATCH 0/11] rcu: Miscellaneous patches for v7.1 Paul E. McKenney
2026-03-03 23:50 ` [PATCH 01/11] rcutorture: Add a textbook-style trivial preemptible RCU Paul E. McKenney
2026-03-03 23:50 ` [PATCH 02/11] kvm-check-branches.sh: Remove in favor of kvm-series.sh Paul E. McKenney
2026-03-03 23:50 ` [PATCH 03/11] torture: Make hangs more visible in torture.sh output Paul E. McKenney
2026-03-03 23:50 ` [PATCH 04/11] rcutorture: Adjust scenarios for default lazy preemption Paul E. McKenney
2026-03-03 23:50 ` [PATCH 05/11] torture: Print informative message for test without recheck file Paul E. McKenney
2026-03-03 23:50 ` [PATCH 06/11] rcutorture: Fix numeric "test" comparison in srcu_lockdep.sh Paul E. McKenney
2026-03-03 23:50 ` [PATCH 07/11] refscale: Ditch ref_scale_shutdown in favor of torture_shutdown_init() Paul E. McKenney
2026-03-03 23:50 ` [PATCH 08/11] rcuscale: Ditch rcu_scale_shutdown " Paul E. McKenney
2026-03-03 23:50 ` [PATCH 09/11] srcu: Fix SRCU read flavor macro comments Paul E. McKenney
2026-03-03 23:50 ` [PATCH 10/11] srcu: Fix s/they disables/they disable/ typo in srcu_read_unlock_fast() Paul E. McKenney
2026-03-03 23:50 ` [PATCH 11/11] rcu-tasks: Document that RCU Tasks Trace grace periods now imply RCU grace periods Paul E. McKenney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox