From c6f4e552e1eae4a5726230254108213b085e1ae3 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sat, 15 Nov 2025 19:07:41 -0800 Subject: rcutorture: Add a textbook-style trivial preemptible RCU 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. ] Signed-off-by: Joel Fernandes --- .../testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT | 12 ++++++++++++ .../selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT.boot | 3 +++ 2 files changed, 15 insertions(+) create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL-PREEMPT.boot (limited to 'tools/testing') 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 000000000000..8230b14bfe68 --- /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 000000000000..299cd3a12df6 --- /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 -- cgit v1.2.3 From 69642000bbc57c2e42708d7186b3ba0deca53f6d Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 28 Dec 2025 16:27:18 -0800 Subject: kvm-check-branches.sh: Remove in favor of kvm-series.sh 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 Signed-off-by: Joel Fernandes --- .../selftests/rcutorture/bin/kvm-check-branches.sh | 102 --------------------- 1 file changed, 102 deletions(-) delete mode 100755 tools/testing/selftests/rcutorture/bin/kvm-check-branches.sh (limited to 'tools/testing') 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 ed0ec7f0927e..000000000000 --- 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 - -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 -- cgit v1.2.3 From 08d5cade666dc4a0f8e9a43a738796a92336f276 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 19 Jan 2026 20:33:48 -0800 Subject: torture: Make hangs more visible in torture.sh output This commit labels "QEMU killed" lines so that they will be picked up by torture.sh processing. Signed-off-by: Paul E. McKenney Signed-off-by: Joel Fernandes --- 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(-) (limited to 'tools/testing') diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh index de65d77b47ff..4791774b8485 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 21e6ba3615f6..be1e943ca4d5 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 -- cgit v1.2.3 From 6778178c3b07c926d8a9af515c5af73f6bdebacf Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 26 Jan 2026 17:50:48 -0800 Subject: torture: Print informative message for test without recheck file 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 Signed-off-by: Joel Fernandes --- tools/testing/selftests/rcutorture/bin/kvm-recheck.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools/testing') diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh index 4791774b8485..63bbbdd5f4ef 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 -- cgit v1.2.3 From df6e6ae18fe776e1ae5dfa8e5104980df608912d Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 28 Jan 2026 12:42:24 -0800 Subject: rcutorture: Fix numeric "test" comparison in srcu_lockdep.sh 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 Signed-off-by: Joel Fernandes --- tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/testing') diff --git a/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh b/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh index 208be7d09a61..4e98c697def4 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" -- cgit v1.2.3 From b0c8dd5097aaa7bfc70c8933de6be0dcdc995592 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 5 Feb 2026 13:43:32 -0800 Subject: refscale: Ditch ref_scale_shutdown in favor of torture_shutdown_init() 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 Signed-off-by: Joel Fernandes --- kernel/rcu/refscale.c | 51 ++++++---------------- .../rcutorture/configs/refscale/ver_functions.sh | 2 +- 2 files changed, 15 insertions(+), 38 deletions(-) (limited to 'tools/testing') diff --git a/kernel/rcu/refscale.c b/kernel/rcu/refscale.c index c158b6a947cd..a2d9d75d88a1 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 748465627601..219fac070af2 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 } -- cgit v1.2.3 From 359cf5c942b8fce9cf2b7f3c1eb5b8186f0d9b30 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 8 Feb 2026 19:03:30 -0800 Subject: rcuscale: Ditch rcu_scale_shutdown in favor of torture_shutdown_init() 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 Signed-off-by: Joel Fernandes --- kernel/rcu/rcuscale.c | 78 ++++++---------------- .../rcutorture/configs/rcuscale/ver_functions.sh | 2 +- 2 files changed, 22 insertions(+), 58 deletions(-) (limited to 'tools/testing') diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index 4ac2b134a983..ac0b1c6b7dae 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -79,12 +79,6 @@ MODULE_AUTHOR("Paul E. McKenney "); * 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 28070b43f017..b78ddc243d89 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 } -- cgit v1.2.3 From 18a6770f1f9899d3ce2d54dba0bdaa5a7e2bdd24 Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Mon, 5 Jan 2026 03:42:41 -0500 Subject: rcutorture: Add NOCB01 config for RCU_LAZY torture testing Add new rcutorture config NOCB01 that enables CONFIG_RCU_LAZY combined with CONFIG_RCU_NOCB_CPU to exercise the lazy callback code paths in the NOCB implementation. This config exercises lazy callback paths not covered by other configs, including lazy-only wake and lazy defer logic. This config is not added to CFLIST to avoid increasing the default test duration; it can be run explicitly when lazy callback testing is needed. Acked-by: Frederic Weisbecker Reviewed-by: Paul E. McKenney Tested-by: Paul E. McKenney Signed-off-by: Joel Fernandes --- .../testing/selftests/rcutorture/configs/rcu/NOCB01 | 21 +++++++++++++++++++++ .../selftests/rcutorture/configs/rcu/NOCB01.boot | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/NOCB01 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/NOCB01.boot (limited to 'tools/testing') diff --git a/tools/testing/selftests/rcutorture/configs/rcu/NOCB01 b/tools/testing/selftests/rcutorture/configs/rcu/NOCB01 new file mode 100644 index 000000000000..bbe6d28210ab --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/rcu/NOCB01 @@ -0,0 +1,21 @@ +CONFIG_SMP=y +CONFIG_NR_CPUS=8 +CONFIG_PREEMPT_NONE=n +CONFIG_PREEMPT_VOLUNTARY=n +CONFIG_PREEMPT=y +#CHECK#CONFIG_PREEMPT_RCU=y +CONFIG_HZ_PERIODIC=n +CONFIG_NO_HZ_IDLE=y +CONFIG_NO_HZ_FULL=n +CONFIG_RCU_TRACE=y +CONFIG_HOTPLUG_CPU=y +CONFIG_RCU_FANOUT=3 +CONFIG_RCU_FANOUT_LEAF=2 +CONFIG_RCU_NOCB_CPU=y +CONFIG_DEBUG_LOCK_ALLOC=n +CONFIG_PROVE_LOCKING=n +CONFIG_RCU_BOOST=n +CONFIG_DEBUG_OBJECTS_RCU_HEAD=n +CONFIG_RCU_EXPERT=y +CONFIG_RCU_EQS_DEBUG=y +CONFIG_RCU_LAZY=y diff --git a/tools/testing/selftests/rcutorture/configs/rcu/NOCB01.boot b/tools/testing/selftests/rcutorture/configs/rcu/NOCB01.boot new file mode 100644 index 000000000000..5130bc84c435 --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/rcu/NOCB01.boot @@ -0,0 +1,2 @@ +rcupdate.rcu_self_test=1 +rcu_nocbs=all -- cgit v1.2.3 From 6c3d9ad795a212ccfdfc0359524ab0d040c58757 Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Mon, 5 Jan 2026 03:42:56 -0500 Subject: rcutorture: Add NOCB02 config for nocb poll mode testing Add new rcutorture config NOCB02 that enables rcu_nocb_poll boot parameter combined with CONFIG_RCU_NOCB_CPU to exercise the polling mode code paths in the NOCB implementation. This config exercises poll-mode paths not covered by other configs, where callback invocation uses active polling instead of kthread wakeups. This config is not added to CFLIST to avoid increasing the default test duration; it can be run explicitly when poll-mode testing is needed. Acked-by: Frederic Weisbecker Reviewed-by: Paul E. McKenney Tested-by: Paul E. McKenney Signed-off-by: Joel Fernandes --- .../testing/selftests/rcutorture/configs/rcu/NOCB02 | 20 ++++++++++++++++++++ .../selftests/rcutorture/configs/rcu/NOCB02.boot | 3 +++ 2 files changed, 23 insertions(+) create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/NOCB02 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/NOCB02.boot (limited to 'tools/testing') diff --git a/tools/testing/selftests/rcutorture/configs/rcu/NOCB02 b/tools/testing/selftests/rcutorture/configs/rcu/NOCB02 new file mode 100644 index 000000000000..4c2b8cd6d8fd --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/rcu/NOCB02 @@ -0,0 +1,20 @@ +CONFIG_SMP=y +CONFIG_NR_CPUS=8 +CONFIG_PREEMPT_NONE=n +CONFIG_PREEMPT_VOLUNTARY=n +CONFIG_PREEMPT=y +#CHECK#CONFIG_PREEMPT_RCU=y +CONFIG_HZ_PERIODIC=n +CONFIG_NO_HZ_IDLE=y +CONFIG_NO_HZ_FULL=n +CONFIG_RCU_TRACE=y +CONFIG_HOTPLUG_CPU=y +CONFIG_RCU_FANOUT=3 +CONFIG_RCU_FANOUT_LEAF=2 +CONFIG_RCU_NOCB_CPU=y +CONFIG_DEBUG_LOCK_ALLOC=n +CONFIG_PROVE_LOCKING=n +CONFIG_RCU_BOOST=n +CONFIG_DEBUG_OBJECTS_RCU_HEAD=n +CONFIG_RCU_EXPERT=y +CONFIG_RCU_EQS_DEBUG=y diff --git a/tools/testing/selftests/rcutorture/configs/rcu/NOCB02.boot b/tools/testing/selftests/rcutorture/configs/rcu/NOCB02.boot new file mode 100644 index 000000000000..c212ae299b0b --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/rcu/NOCB02.boot @@ -0,0 +1,3 @@ +rcupdate.rcu_self_test=1 +rcu_nocbs=all +rcu_nocb_poll -- cgit v1.2.3