Torture-test updates
Subsystems (6)
cover Torture-test updates
Hello!
This series contains torture-test updates:
1. Move SRCU status printing to SRCU implementations.
2. Print SRCU lock/unlock totals because I am getting tired of
doing the addition in my head.
3. Remove CONFIG_TASKS_RCU ifdef from rcuperf.c.
4. Select CONFIG_PROVE_LOCKING for Tiny SRCU scenario.
5. Add --kconfig argument to kvm.sh to allow test runs to override
the test-scenario files.
6. Don't wait for kernel when all builds fail.
7. Enable SRCU readers from timer handler.
8. Place event-traced strings into trace buffer.
9. Use nr_cpus rather than maxcpus to limit test size.
10. Add task's CPU for rcutorture writer stalls.
11. Eliminate unused ts_rem local from rcu_trace_clock_local().
12. Add last-CPU to GP-kthread starvation messages.
13. Invoke call_rcu() from timer handler.
Thanx, Paul
------------------------------------------------------------------------
include/linux/srcutiny.h | 13 ++ include/linux/srcutree.h | 1 include/trace/events/rcu.h | 7 - kernel/rcu/rcuperf.c | 17 --- kernel/rcu/rcutorture.c | 66 ++++--------- kernel/rcu/srcutree.c | 39 +++++++ kernel/rcu/tree.c | 5 tools/testing/selftests/rcutorture/bin/config_override.sh | 61 ++++++++++++ tools/testing/selftests/rcutorture/bin/functions.sh | 27 +++++ tools/testing/selftests/rcutorture/bin/kvm-build.sh | 11 -- tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh | 58 +++++------ tools/testing/selftests/rcutorture/bin/kvm.sh | 34 +++++- tools/testing/selftests/rcutorture/configs/rcu/BUSTED.boot | 2 tools/testing/selftests/rcutorture/configs/rcu/SRCU-u | 3 tools/testing/selftests/rcutorture/configs/rcu/TREE01.boot | 2 15 files changed, 233 insertions(+), 113 deletions(-)
PATCH 1/13 rcutorture: Move SRCU status printing to SRCU implementations
This commit gets rid of some ugly #ifdefs in rcutorture.c by moving the SRCU status printing to the SRCU implementations.
--- include/linux/srcutiny.h | 13 +++++++++++++ include/linux/srcutree.h | 1 + kernel/rcu/rcutorture.c | 39 +-------------------------------------- kernel/rcu/srcutree.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 38 deletions(-)
include/linux/srcutiny.h +13 -0
@@ -87,4 +87,17 @@ static inline void srcu_barrier(struct srcu_struct *sp) synchronize_srcu(sp); } +/* Defined here to avoid size increase for non-torture kernels. */ +static inline void srcu_torture_stats_print (struct srcu_struct *sp, +char *tt,char *tf) +{ +int idx; + + idx =READ_ONCE (sp->srcu_idx) &0x1 ; +pr_alert ("%s%s Tiny SRCU per-CPU(idx=%d): (%hd,%hd)\n" , + tt, tf, idx, +READ_ONCE (sp->srcu_lock_nesting[!idx]), +READ_ONCE (sp->srcu_lock_nesting[idx])); +} +#endif
include/linux/srcutree.h +1 -0
@@ -141,5 +141,6 @@ void process_srcu(struct work_struct *work);void synchronize_srcu_expedited (struct srcu_struct *sp);void srcu_barrier (struct srcu_struct *sp); +void srcu_torture_stats_print (struct srcu_struct *sp,char *tt,char *tf);#endif
kernel/rcu/rcutorture.c +1 -38
@@ -561,44 +561,7 @@ static void srcu_torture_barrier(void)static void srcu_torture_stats (void ) { -int __maybe_unused cpu; -int idx; - -#ifdef CONFIG_TREE_SRCU - idx = srcu_ctlp->srcu_idx &0x1 ; -pr_alert ("%s%s Tree SRCU per-CPU(idx=%d):" , - torture_type,TORTURE_FLAG , idx); -for_each_possible_cpu (cpu) { -unsigned long l0, l1; -unsigned long u0, u1; -long c0, c1; -struct srcu_data *counts; - - counts =per_cpu_ptr (srcu_ctlp->sda, cpu); - u0 = counts->srcu_unlock_count[!idx]; - u1 = counts->srcu_unlock_count[idx]; - -/* -* Make sure that a lock is always counted if the corresponding -* unlock is counted. -*/ -smp_rmb (); - - l0 = counts->srcu_lock_count[!idx]; - l1 = counts->srcu_lock_count[idx]; - - c0 = l0 - u0; - c1 = l1 - u1; -pr_cont (" %d(%ld,%ld)" , cpu, c0, c1); - } -pr_cont ("\n" ); -#elif defined(CONFIG_TINY_SRCU ) - idx =READ_ONCE (srcu_ctlp->srcu_idx) &0x1 ; -pr_alert ("%s%s Tiny SRCU per-CPU(idx=%d): (%hd,%hd)\n" , - torture_type,TORTURE_FLAG , idx, -READ_ONCE (srcu_ctlp->srcu_lock_nesting[!idx]), -READ_ONCE (srcu_ctlp->srcu_lock_nesting[idx])); -#endif +srcu_torture_stats_print (srcu_ctlp, torture_type,TORTURE_FLAG ); }static void srcu_torture_synchronize_expedited (void )
kernel/rcu/srcutree.c +34 -0
@@ -1217,6 +1217,40 @@ void srcutorture_get_gp_data(enum rcutorture_type test_type, }EXPORT_SYMBOL_GPL (srcutorture_get_gp_data); +void srcu_torture_stats_print (struct srcu_struct *sp,char *tt,char *tf) +{ +int cpu; +int idx; + + idx = sp->srcu_idx &0x1 ; +pr_alert ("%s%s Tree SRCU per-CPU(idx=%d):" , tt, tf, idx); +for_each_possible_cpu (cpu) { +unsigned long l0, l1; +unsigned long u0, u1; +long c0, c1; +struct srcu_data *counts; + + counts =per_cpu_ptr (sp->sda, cpu); + u0 = counts->srcu_unlock_count[!idx]; + u1 = counts->srcu_unlock_count[idx]; + +/* +* Make sure that a lock is always counted if the corresponding +* unlock is counted. +*/ +smp_rmb (); + + l0 = counts->srcu_lock_count[!idx]; + l1 = counts->srcu_lock_count[idx]; + + c0 = l0 - u0; + c1 = l1 - u1; +pr_cont (" %d(%ld,%ld)" , cpu, c0, c1); + } +pr_cont ("\n" ); +} +EXPORT_SYMBOL_GPL (srcu_torture_stats_print); +static int __init srcu_bootup_announce (void ) {pr_info ("Hierarchical SRCU implementation.\n" );
Signature · 1 line
2.5.2
PATCH 2/13 rcutorture: Print SRCU lock/unlock totals
In reply to Paul E. McKenneyThis commit adds printing of SRCU lock/unlock totals, which are just the sums of the per-CPU counts. Saves a bit of mental arithmetic.
--- kernel/rcu/srcutree.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/rcu/srcutree.c +4 -1
@@ -1221,6 +1221,7 @@ void srcu_torture_stats_print(struct srcu_struct *sp, char *tt, char *tf) {int cpu;int idx; +unsigned long s0 =0 , s1 =0 ; idx = sp->srcu_idx &0x1 ;pr_alert ("%s%s Tree SRCU per-CPU(idx=%d):" , tt, tf, idx);
@@ -1246,8 +1247,10 @@ void srcu_torture_stats_print(struct srcu_struct *sp, char *tt, char *tf) c0 = l0 - u0; c1 = l1 - u1;pr_cont (" %d(%ld,%ld)" , cpu, c0, c1); + s0 += c0; + s1 += c1; } -pr_cont ("\n" ); +pr_cont (" T(%ld,%ld)\n" , s0, s1); }EXPORT_SYMBOL_GPL (srcu_torture_stats_print);
Signature · 1 line
2.5.2
PATCH 3/13 rcu: Remove CONFIG_TASKS_RCU ifdef from rcuperf.c
In reply to Paul E. McKenneyThe synchronize_rcu_tasks() and call_rcu_tasks() APIs are now available regardless of kernel configuration, so this commit removes the CONFIG_TASKS_RCU ifdef from rcuperf.c.
--- kernel/rcu/rcuperf.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-)
kernel/rcu/rcuperf.c +1 -16
@@ -317,8 +317,6 @@ static struct rcu_perf_ops sched_ops = { .name = "sched" }; -#ifdef CONFIG_TASKS_RCU -/* * Definitions for RCU-tasks perf testing. */
@@ -346,24 +344,11 @@ static struct rcu_perf_ops tasks_ops = { .name = "tasks" }; -#define RCUPERF_TASKS_OPS &tasks_ops, -static bool __maybe_unused torturing_tasks (void ) {return cur_ops == &tasks_ops; } -#else /* #ifdef CONFIG_TASKS_RCU */ - -#define RCUPERF_TASKS_OPS - -static bool __maybe_unused torturing_tasks (void ) -{ -return false; -} - -#endif /* #else #ifdef CONFIG_TASKS_RCU */ -/* * If performance tests complete, wait for shutdown to commence. */
@@ -658,7 +643,7 @@ rcu_perf_init(void)int firsterr =0 ;static struct rcu_perf_ops *perf_ops[] = { &rcu_ops, &rcu_bh_ops, &srcu_ops, &srcud_ops, &sched_ops, -RCUPERF_TASKS_OPS + &tasks_ops, };if (!torture_init_begin (perf_type, verbose, &perf_runnable))
Signature · 1 line
2.5.2
PATCH 4/13 rcutorture: Select CONFIG_PROVE_LOCKING for Tiny SRCU scenario
In reply to Paul E. McKenneyThis commit selects CONFIG_PROVE_LOCKING for the SRCU-u scenario to get better test coverage.
--- tools/testing/selftests/rcutorture/configs/rcu/SRCU-u | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/rcutorture/configs/rcu/SRCU-u +2 -1
@@ -4,6 +4,7 @@ CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n #CHECK#CONFIG_TINY_SRCU=y CONFIG_RCU_TRACE=n -CONFIG_DEBUG_LOCK_ALLOC=n +CONFIG_DEBUG_LOCK_ALLOC=y +CONFIG_PROVE_LOCKING=y CONFIG_DEBUG_OBJECTS_RCU_HEAD=n CONFIG_PREEMPT_COUNT=n
Signature · 1 line
2.5.2
PATCH 5/13 torture: Add --kconfig argument to kvm.sh
In reply to Paul E. McKenneyCurrently, testing a variant of an existing scenario requires editing that scenario's file or creating a new scenario file. This is messy and error prone with respect to changes to scenarios.
This commit therefore adds a --kconfig argument to kvm.sh, so that '--kconfig "CONFIG_RCU_TRACE=y CONFIG_RCU_EQS_DEBUG=n" will override those two Kconfig options. In addition, there is now clear precedence:
the config fragment overrides CFcommon, and the --kconfig argument overrides both.
--- .../selftests/rcutorture/bin/config_override.sh | 61 ++++++++++++++++++++++ .../testing/selftests/rcutorture/bin/kvm-build.sh | 11 +--- .../selftests/rcutorture/bin/kvm-test-1-run.sh | 54 +++++++++---------- tools/testing/selftests/rcutorture/bin/kvm.sh | 8 +++ 4 files changed, 96 insertions(+), 38 deletions(-) create mode 100755 tools/testing/selftests/rcutorture/bin/config_override.sh
tools/testing/selftests/rcutorture/bin/config_override.sh new file +61 -0
@@ -0,0 +1,61 @@ +#!/bin/bash +# +# config_override.sh base override +# +# Combines base and override, removing any Kconfig options from base +# that conflict with any in override, concatenating what remains and +# sending the result to standard output. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, you can access it online at +# http://www.gnu.org/licenses/gpl-2.0.html. +# +# Copyright (C) IBM Corporation, 2017 +# +# Authors: Paul E. McKenney <[email protected]> + +base=$1 +if test -r $base +then + : +else + echo Base file $base unreadable!!! + exit 1 +fi + +override=$2 +if test -r $override +then + : +else + echo Override file $override unreadable!!! + exit 1 +fi + +T=/tmp/config_override.sh.$$ +trap 'rm -rf $T' 0 +mkdir $T + +sed < $override -e 's/^/grep -v "/' -e 's/=.*$/="/' | + awk ' + { + if (last) + print last " |"; + last = $0; + } + END { + if (last) + print last; + }' > $T/script +sh $T/script < $base +cat $override
tools/testing/selftests/rcutorture/bin/kvm-build.sh +2 -9
@@ -2,7 +2,7 @@ # # Build a kvm-ready Linux kernel from the tree in the current directory. # -# Usage: kvm-build.sh config-template build-dir more-configs +# Usage: kvm-build.sh config-template build-dir # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by
@@ -34,24 +34,17 @@ then echo "kvm-build.sh :$builddir: Not a writable directory, cannot build into it" exit 1 fi -moreconfigs=${3} -if test -z "$moreconfigs" -o ! -r "$moreconfigs" -then - echo "kvm-build.sh :$moreconfigs: Not a readable file" - exit 1 -fi T=/tmp/test-linux.sh.$$ trap 'rm -rf $T' 0 mkdir $T -grep -v 'CONFIG_[A-Z]*_TORTURE_TEST=' < ${config_template} > $T/config +cp ${config_template} $T/config cat << ___EOF___ >> $T/config CONFIG_INITRAMFS_SOURCE="$TORTURE_INITRD" CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_CONSOLE=y ___EOF___ -cat $moreconfigs >> $T/config configinit.sh $T/config O=$builddir retval=$?
tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +25 -29
83 lines not on this page · raw message
tools/testing/selftests/rcutorture/bin/kvm.sh +8 -0
@@ -41,6 +41,7 @@ PATH=${KVM}/bin:$PATH; export PATH TORTURE_DEFCONFIG=defconfig TORTURE_BOOT_IMAGE="" TORTURE_INITRD="$KVM/initrd"; export TORTURE_INITRD +TORTURE_KCONFIG_ARG="" TORTURE_KMAKE_ARG="" TORTURE_SHUTDOWN_GRACE=180 TORTURE_SUITE=rcu
@@ -65,6 +66,7 @@ usage () { echo " --duration minutes" echo " --interactive" echo " --jitter N [ maxsleep (us) [ maxspin (us) ] ]" + echo " --kconfig Kconfig-options" echo " --kmake-arg kernel-make-arguments" echo " --mac nn:nn:nn:nn:nn:nn" echo " --no-initrd"
@@ -129,6 +131,11 @@ do jitter="$2" shift ;; + --kconfig) + checkarg --kconfig "(Kconfig options)" $# "$2" '^CONFIG_[A-Z0-9_]\+=\([ynm]\|[0-9]\+\)\( CONFIG_[A-Z0-9_]\+=\([ynm]\|[0-9]\+\)\)*$' '^error$' + TORTURE_KCONFIG_ARG="$2" + shift + ;; --kmake-arg) checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$' TORTURE_KMAKE_ARG="$2"
@@ -275,6 +282,7 @@ TORTURE_BOOT_IMAGE="$TORTURE_BOOT_IMAGE"; export TORTURE_BOOT_IMAGE TORTURE_BUILDONLY="$TORTURE_BUILDONLY"; export TORTURE_BUILDONLY TORTURE_DEFCONFIG="$TORTURE_DEFCONFIG"; export TORTURE_DEFCONFIG TORTURE_INITRD="$TORTURE_INITRD"; export TORTURE_INITRD +TORTURE_KCONFIG_ARG="$TORTURE_KCONFIG_ARG"; export TORTURE_KCONFIG_ARG TORTURE_KMAKE_ARG="$TORTURE_KMAKE_ARG"; export TORTURE_KMAKE_ARG TORTURE_QEMU_CMD="$TORTURE_QEMU_CMD"; export TORTURE_QEMU_CMD TORTURE_QEMU_INTERACTIVE="$TORTURE_QEMU_INTERACTIVE"; export TORTURE_QEMU_INTERACTIVE
Signature · 1 line
2.5.2
PATCH 6/13 rcutorture: Don't wait for kernel when all builds fail
In reply to Paul E. McKenneyCurrently, rcutorture groups runs in batches, building each scenario in a given batch, then invoking qemu to run all the kernels in the batch. Of course, if a given scenario's kernel fails to build, there is no qemu run for that scenario. And if all of the kernels in a given batch fail to build, there are no runs, and rcutorture immediately starts on the next batch.
But not if --jitter has been specified, which it is by default. In this case, the jitter scripts are started unconditionally, and rcutorture waits for them to complete, even though there are no kernels to run.
This commit therefore checks for this situation, and refuses to start jitter unless at least one of the kernels in the batch built successfully. This saves substantial time when all scenarios' kernels fail to build, particularly if a long --duration was specified.
--- .../selftests/rcutorture/bin/kvm-test-1-run.sh | 4 ++++ tools/testing/selftests/rcutorture/bin/kvm.sh | 25 ++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-)
tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +4 -0
@@ -96,6 +96,8 @@ then KERNEL=$base_resdir/${BOOT_IMAGE##*/} # use the last component of ${BOOT_IMAGE} ln -s $base_resdir/Make*.out $resdir # for kvm-recheck.sh ln -s $base_resdir/.config $resdir # for kvm-recheck.sh + # Arch-independent indicator + touch $resdir/builtkernel elif kvm-build.sh $T/Kc2 $builddir then # Had to build a kernel for this test.
@@ -108,6 +110,8 @@ then then cp $builddir/$BOOT_IMAGE $resdir KERNEL=$resdir/${BOOT_IMAGE##*/} + # Arch-independent indicator + touch $resdir/builtkernel else echo No identifiable boot image, not running KVM, see $resdir. echo Do the torture scripts know about your architecture?
tools/testing/selftests/rcutorture/bin/kvm.sh +18 -7
@@ -332,6 +332,7 @@ function dump(first, pastlast, batchnum) { print "echo ----Start batch " batchnum ": `date`"; print "echo ----Start batch " batchnum ": `date` >> " rd "/log"; + print "needqemurun=" jn=1 for (j = first; j < pastlast; j++) { builddir=KVM "/b" jn
@@ -367,10 +368,11 @@ function dump(first, pastlast, batchnum) for (j = 1; j < jn; j++) { builddir=KVM "/b" j print "rm -f " builddir ".ready" - print "if test -z \"$TORTURE_BUILDONLY\"" + print "if test -f \"" rd cfr[j] "/builtkernel\"" print "then" - print "\techo ----", cfr[j], cpusr[j] ovf ": Starting kernel. `date`"; - print "\techo ----", cfr[j], cpusr[j] ovf ": Starting kernel. `date` >> " rd "/log"; + print "\techo ----", cfr[j], cpusr[j] ovf ": Kernel present. `date`"; + print "\techo ----", cfr[j], cpusr[j] ovf ": Kernel present. `date` >> " rd "/log"; + print "\tneedqemurun=1" print "fi" } njitter = 0;
@@ -385,13 +387,22 @@ function dump(first, pastlast, batchnum) njitter = 0; print "echo Build-only run, so suppressing jitter >> " rd "/log" } - for (j = 0; j < njitter; j++) - print "jitter.sh " j " " dur " " ja[2] " " ja[3] "&" - print "wait" - print "if test -z \"$TORTURE_BUILDONLY\"" + if (TORTURE_BUILDONLY) { + print "needqemurun=" + } + print "if test -n \"$needqemurun\"" print "then" + print "\techo ---- Starting kernels. `date`"; + print "\techo ---- Starting kernels. `date` >> " rd "/log"; + for (j = 0; j < njitter; j++) + print "\tjitter.sh " j " " dur " " ja[2] " " ja[3] "&" + print "\twait" print "\techo ---- All kernel runs complete. `date`"; print "\techo ---- All kernel runs complete. `date` >> " rd "/log"; + print "else" + print "\twait" + print "\techo ---- No kernel runs. `date`"; + print "\techo ---- No kernel runs. `date` >> " rd "/log"; print "fi" for (j = 1; j < jn; j++) { builddir=KVM "/b" j
Signature · 1 line
2.5.2
PATCH 7/13 rcutorture: Enable SRCU readers from timer handler
In reply to Paul E. McKenneyNow that it is legal to invoke srcu_read_lock() and srcu_read_unlock() for a given srcu_struct from both process context and {soft,}irq handlers, it is time to test it. This commit therefore enables testing of SRCU readers from rcutorture's timer handler, using in_task() to determine whether or not it is safe to sleep in the SRCU read-side critical sections.
--- kernel/rcu/rcutorture.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/rcu/rcutorture.c +3 -1
@@ -522,7 +522,7 @@ static void srcu_read_delay(struct torture_random_state *rrsp) delay =torture_random (rrsp) % (nrealreaders *2 * longdelay * uspertick); -if (!delay) +if (!delay &&in_task ())schedule_timeout_interruptible (longdelay);else rcu_read_delay (rrsp);
@@ -583,6 +583,7 @@ static struct rcu_torture_ops srcu_ops = { .call = srcu_torture_call, .cb_barrier = srcu_torture_barrier, .stats = srcu_torture_stats, + .irq_capable = 1, .name = "srcu" };
@@ -615,6 +616,7 @@ static struct rcu_torture_ops srcud_ops = { .call = srcu_torture_call, .cb_barrier = srcu_torture_barrier, .stats = srcu_torture_stats, + .irq_capable = 1, .name = "srcud" };
Signature · 1 line
2.5.2
PATCH 8/13 rcutorture: Place event-traced strings into trace buffer
In reply to Paul E. McKenneyStrings used in event tracing need to be specially handled, for example, being copied to the trace buffer instead of being pointed to by the trace buffer. Although the TPS() macro can be used to "launder" pointed-to strings, this might not be all that effective within a loadable module. This commit therefore copies rcutorture's strings to the trace buffer.
--- include/trace/events/rcu.h | 7 +++++-- kernel/rcu/rcutorture.c | 2 +- tools/testing/selftests/rcutorture/configs/rcu/BUSTED.boot | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-)
include/trace/events/rcu.h +5 -2
@@ -703,6 +703,7 @@ TRACE_EVENT(rcu_batch_end,* at the beginning and end of the read, respectively. Note that the * callback address can be NULL. */ +#define RCUTORTURENAME_LEN 8 TRACE_EVENT(rcu_torture_read, TP_PROTO(const char *rcutorturename, struct rcu_head *rhp,
@@ -711,7 +712,7 @@ TRACE_EVENT(rcu_torture_read,TP_ARGS (rcutorturename, rhp, secs, c_old, c),TP_STRUCT__entry ( - __field(const char *, rcutorturename) + __field(char, rcutorturename[RCUTORTURENAME_LEN]) __field(struct rcu_head *, rhp) __field(unsigned long, secs) __field(unsigned long, c_old)
@@ -719,7 +720,9 @@ TRACE_EVENT(rcu_torture_read, ),TP_fast_assign ( - __entry->rcutorturename = rcutorturename; +strncpy (__entry->rcutorturename, rcutorturename, + RCUTORTURENAME_LEN); + __entry->rcutorturename[RCUTORTURENAME_LEN -1 ] =0 ; __entry->rhp = rhp; __entry->secs = secs; __entry->c_old = c_old;
kernel/rcu/rcutorture.c +1 -1
@@ -496,7 +496,7 @@ static struct rcu_torture_ops rcu_busted_ops = { .fqs = NULL, .stats = NULL, .irq_capable = 1, - .name = "rcu_busted" + .name = "busted" };/*
tools/testing/selftests/rcutorture/configs/rcu/BUSTED.boot +1 -1
@@ -1 +1 @@ -rcutorture.torture_type=rcu_busted +rcutorture.torture_type=busted
Signature · 1 line
2.5.2
PATCH 9/13 rcutorture: Use nr_cpus rather than maxcpus to limit test size
In reply to Paul E. McKenneyThe maxcpus= kernel boot parameter limits the number of CPUs brought online at boot time, but it does nothing to prevent additional CPUs from being brought up later. Placing a hard cap on the total number of CPUs is instead the job of the nr_cpus= boot parameter. This commit therefore switches the configfrag_boot_cpus() shell function from maxcpus= to nr_cpus=. This commit also adds a nr_cpus=43 kernel parameter to RCU's TREE01 test scenario, but retains the maxcpus=8 kernel parameter in order to test the ability of RCU expedited grace periods to handle new CPUs coming online for the first time during grace-period initialization. Finally, this commit makes the torture scheduling allow maxcpus= to override other means of specifying the number of CPUs to allow for. This last works because the torture kernel modules size their workloads based on the number of CPUs present at the start of the test, not the ultimate number of CPUs.
--- .../testing/selftests/rcutorture/bin/functions.sh | 27 +++++++++++++++++++++- tools/testing/selftests/rcutorture/bin/kvm.sh | 1 + .../selftests/rcutorture/configs/rcu/TREE01.boot | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-)
tools/testing/selftests/rcutorture/bin/functions.sh +26 -1
@@ -66,9 +66,34 @@ configfrag_boot_params () { # configfrag_boot_cpus bootparam-string config-fragment-file config-cpus # -# Decreases number of CPUs based on any maxcpus= boot parameters specified. +# Decreases number of CPUs based on any nr_cpus= boot parameters specified. configfrag_boot_cpus () { local bootargs="`configfrag_boot_params "$1" "$2"`" + local nr_cpus + if echo "${bootargs}" | grep -q 'nr_cpus=[0-9]' + then + nr_cpus="`echo "${bootargs}" | sed -e 's/^.*nr_cpus=\([0-9]*\).*$/\1/'`" + if test "$3" -gt "$nr_cpus" + then + echo $nr_cpus + else + echo $3 + fi + else + echo $3 + fi +} + +# configfrag_boot_maxcpus bootparam-string config-fragment-file config-cpus +# +# Decreases number of CPUs based on any maxcpus= boot parameters specified. +# This allows tests where additional CPUs come online later during the +# test run. However, the torture parameters will be set based on the +# number of CPUs initially present, so the scripting should schedule +# test runs based on the maxcpus= boot parameter controlling the initial +# number of CPUs instead of on the ultimate number of CPUs. +configfrag_boot_maxcpus () { + local bootargs="`configfrag_boot_params "$1" "$2"`" local maxcpus if echo "${bootargs}" | grep -q 'maxcpus=[0-9]' then
tools/testing/selftests/rcutorture/bin/kvm.sh +1 -0
@@ -212,6 +212,7 @@ do then cpu_count=`configNR_CPUS.sh $CONFIGFRAG/$CF1` cpu_count=`configfrag_boot_cpus "$TORTURE_BOOTARGS" "$CONFIGFRAG/$CF1" "$cpu_count"` + cpu_count=`configfrag_boot_maxcpus "$TORTURE_BOOTARGS" "$CONFIGFRAG/$CF1" "$cpu_count"` for ((cur_rep=0;cur_rep<$config_reps;cur_rep++)) do echo $CF1 $cpu_count >> $T/cfgcpu
tools/testing/selftests/rcutorture/configs/rcu/TREE01.boot +1 -1
@@ -1,4 +1,4 @@ -rcutorture.torture_type=rcu_bh maxcpus=8 +rcutorture.torture_type=rcu_bh maxcpus=8 nr_cpus=43 rcutree.gp_preinit_delay=3 rcutree.gp_init_delay=3 rcutree.gp_cleanup_delay=3
Signature · 1 line
2.5.2
PATCH 10/13 rcutorture: Add task's CPU for rcutorture writer stalls
In reply to Paul E. McKenneyIt appears that at least some of the rcutorture writer stall messages coincide with unusually long CPU-online operations, for example, no fewer than 205 seconds in a recent test. It is of course possible that the writer stall is not unrelated to this unusually long CPU-hotplug operation, and so this commit adds the rcutorture writer task's CPU to the stall message to gain more information about this possible connection.
--- kernel/rcu/rcutorture.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/rcu/rcutorture.c +3 -2
@@ -1319,11 +1319,12 @@ rcu_torture_stats_print(void)srcutorture_get_gp_data (cur_ops->ttype, srcu_ctlp, &flags, &gpnum, &completed); wtp =READ_ONCE (writer_task); -pr_alert ("??? Writer stall state %s(%d) g%lu c%lu f%#x ->state %#lx\n" , +pr_alert ("??? Writer stall state %s(%d) g%lu c%lu f%#x ->state %#lx cpu %d\n" ,rcu_torture_writer_state_getname (), rcu_torture_writer_state, gpnum, completed, flags, - wtp ==NULL ? ~0UL : wtp->state); + wtp ==NULL ? ~0UL : wtp->state, + wtp ==NULL ?-1 : (int )task_cpu (wtp));show_rcu_gp_kthreads ();rcu_ftrace_dump (DUMP_ALL ); }
Signature · 1 line
2.5.2
PATCH 11/13 rcutorture: Eliminate unused ts_rem local from rcu_trace_clock_local()
In reply to Paul E. McKenneyThis commit removes an unused local variable named ts_rem that is marked __maybe_unused. Yes, the variable was assigned to, but it was never used beyond that point, hence not needed.
--- kernel/rcu/rcutorture.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/rcu/rcutorture.c +2 -1
@@ -199,7 +199,8 @@ MODULE_PARM_DESC(torture_runnable, "Start rcutorture at boot"); static u64 notrace rcu_trace_clock_local(void) {u64 ts =trace_clock_local (); -unsigned long __maybe_unused ts_rem =do_div (ts,NSEC_PER_USEC ); + + (void )do_div (ts,NSEC_PER_USEC );return ts; }#else /* #ifdef CONFIG_RCU_TRACE */
Signature · 1 line
2.5.2
PATCH 12/13 rcu: Add last-CPU to GP-kthread starvation messages
In reply to Paul E. McKenneyThis commit augments the grace-period-kthread starvation debugging messages by adding the last CPU that ran the kthread.
--- kernel/rcu/tree.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/rcu/tree.c +3 -2
@@ -1358,12 +1358,13 @@ static void rcu_check_gp_kthread_starvation(struct rcu_state *rsp) j = jiffies; gpa =READ_ONCE (rsp->gp_activity);if (j - gpa >2 *HZ ) { -pr_err ("%s kthread starved for %ld jiffies! g%lu c%lu f%#x %s(%d) ->state=%#lx\n" , +pr_err ("%s kthread starved for %ld jiffies! g%lu c%lu f%#x %s(%d) ->state=%#lx ->cpu=%d\n" , rsp->name, j - gpa, rsp->gpnum, rsp->completed, rsp->gp_flags,gp_state_getname (rsp->gp_state), rsp->gp_state, - rsp->gp_kthread ? rsp->gp_kthread->state : ~0 ); + rsp->gp_kthread ? rsp->gp_kthread->state : ~0 , + rsp->gp_kthread ?task_cpu (rsp->gp_kthread) :-1 );if (rsp->gp_kthread) {sched_show_task (rsp->gp_kthread);wake_up_process (rsp->gp_kthread);
Signature · 1 line
2.5.2
PATCH 13/13 rcutorture: Invoke call_rcu() from timer handler
In reply to Paul E. McKenneyThe Linux kernel invokes call_rcu() from various interrupt/softirq handlers, but rcutorture does not. This commit therefore adds this behavior to rcutorture's repertoire.
--- kernel/rcu/rcutorture.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
kernel/rcu/rcutorture.c +13 -0
@@ -1080,6 +1080,11 @@ rcu_torture_fakewriter(void *arg)return 0 ; } +static void rcu_torture_timer_cb (struct rcu_head *rhp) +{ +kfree (rhp); +} +/* * RCU torture reader from timer handler. Dereferences rcu_torture_current, * incrementing the corresponding element of the pipeline array. The
@@ -1142,6 +1147,14 @@ static void rcu_torture_timer(unsigned long unused)__this_cpu_inc (rcu_torture_batch[completed]);preempt_enable (); cur_ops->readunlock (idx); + +/* Test call_rcu() invocation from interrupt handler. */ +if (cur_ops->call) { +struct rcu_head *rhp =kmalloc (sizeof (*rhp),GFP_NOWAIT ); + +if (rhp) + cur_ops->call (rhp, rcu_torture_timer_cb); + } }/*
Signature · 1 line
2.5.2