Torture-test changes for 4.7
Subsystems (6)
cover Torture-test changes for 4.7
Hello!
This series contains torture-test changes for RCU, most notably a new test for performance of RCU grace periods named "rcuperf":
1. Update scripting to accommodate rcuperf.
2. Allow for rcupdate.rcu_normal in rcu_torture_writer() decisions.
3. Expedited-GP batch progress access to torturing for progress
statistics.
4. Add RCU grace-period performance tests, AKA "rcuperf".
5. Documentation for rcuperf kernel parameters.
6. Bind rcuperf reader/writer kthreads to CPUs.
7. Set rcuperf writer kthreads to real-time priority.
8. Print measure of batching efficiency.
9. Make rcuperf collect expedited event-trace data.
10. Make scripts analyze rcuperf trace data, if present.
11. Add rcuperf holdoff boot parameter to reduce interference.
12. Avoid RCU CPU stall warning and RT throttling.
13. Add largish-system rcuperf scenario.
14. Do not wake up shutdown wait queue if "shutdown" is false, courtesy
of Artem Savkov.
15. Remove redundant initialization to zero.
16. Consider FROZEN hotplug notifier transitions, courtesy of
Anna-Maria Gleixner.
17. Clarify refusal to run more than one torture test.
18. Kill qemu, not parent process.
19. Convert test duration to seconds early.
20. Add OS-jitter capability.
21. Don't rebuild identical kernel.
22. Dump trace buffer upon shutdown.
23. Add irqs-disabled test for call_rcu().
24. Add boot-time adjustment of leaf fanout.
Thanx, Paul
------------------------------------------------------------------------
Documentation/kernel-parameters.txt | 38 include/linux/rcutiny.h | 16 include/linux/rcutree.h | 2 kernel/rcu/Makefile | 1 kernel/rcu/rcuperf.c | 661 +++++++++- kernel/rcu/rcutorture.c | 12 kernel/rcu/tree.c | 22 kernel/torture.c | 4 lib/Kconfig.debug | 33 tools/testing/selftests/rcutorture/bin/jitter.sh | 83 + tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf-ftrace.sh | 121 + tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf.sh | 116 + tools/testing/selftests/rcutorture/bin/kvm-recheck.sh | 5 tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh | 61 tools/testing/selftests/rcutorture/bin/kvm.sh | 24 tools/testing/selftests/rcutorture/configs/rcu/TREE04 | 2 tools/testing/selftests/rcutorture/configs/rcu/TREE04.boot | 2 tools/testing/selftests/rcutorture/configs/rcuperf/CFLIST | 1 tools/testing/selftests/rcutorture/configs/rcuperf/CFcommon | 2 tools/testing/selftests/rcutorture/configs/rcuperf/TREE | 20 tools/testing/selftests/rcutorture/configs/rcuperf/TREE54 | 23 tools/testing/selftests/rcutorture/configs/rcuperf/ver_functions.sh | 52 22 files changed, 1260 insertions(+), 41 deletions(-)
PATCH 1/24 rcutorture: Update scripting to accommodate rcuperf
This commit adds the scripting changes to add support for the shiny new rcuperf kernel module.
--- .../rcutorture/bin/kvm-recheck-rcuperf.sh | 82 ++++++++++++++++++++++ .../selftests/rcutorture/bin/kvm-recheck.sh | 5 +- tools/testing/selftests/rcutorture/bin/kvm.sh | 2 +- .../selftests/rcutorture/configs/rcuperf/CFLIST | 1 + .../selftests/rcutorture/configs/rcuperf/CFcommon | 2 + .../selftests/rcutorture/configs/rcuperf/TREE | 19 +++++ .../rcutorture/configs/rcuperf/ver_functions.sh | 52 ++++++++++++++ 7 files changed, 161 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf.sh create mode 100644 tools/testing/selftests/rcutorture/configs/rcuperf/CFLIST create mode 100644 tools/testing/selftests/rcutorture/configs/rcuperf/CFcommon create mode 100644 tools/testing/selftests/rcutorture/configs/rcuperf/TREE create mode 100644 tools/testing/selftests/rcutorture/configs/rcuperf/ver_functions.sh
tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf.sh new file +82 -0
@@ -0,0 +1,82 @@ +#!/bin/bash +# +# Analyze a given results directory for rcuperf performance measurements. +# +# Usage: kvm-recheck-rcuperf.sh resdir +# +# 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, 2016 +# +# Authors: Paul E. McKenney <[email protected]> + +i="$1" +if test -d $i +then + : +else + echo Unreadable results directory: $i + exit 1 +fi +. tools/testing/selftests/rcutorture/bin/functions.sh + +configfile=`echo $i | sed -e 's/^.*\///'` + +grep -e '-perf:.*writer-duration' $i/console.log | sed -e 's/^\[[^]]*]//' | +awk ' +{ + gptimes[++n] = $5 / 1000.; + sum += $5 / 1000.; +} + +END { + if (NR <= 0) { + print "No rcuperf records found???" + exit; + } + asort(gptimes); + pct50 = int(NR * 50 / 100); + if (pct50 < 1) + pct50 = 1; + pct90 = int(NR * 90 / 100); + if (pct90 < 1) + pct90 = 1; + pct99 = int(NR * 99 / 100); + if (pct99 < 1) + pct99 = 1; + div = 10 ** int(log(gptimes[pct90]) / log(10) + .5) / 100; + print "Histogram bucket size: " div; + last = gptimes[1] - 10; + count = 0; + for (i = 1; i <= NR; i++) { + current = div * int(gptimes[i] / div); + if (last == current) { + count++; + } else { + if (count > 0) + print last, count; + count = 1; + last = current; + } + } + if (count > 0) + print last, count; + print "Average grace-period duration: " sum / NR " microseconds"; + print "Minimum grace-period duration: " gptimes[1]; + print "50th percentile grace-period duration: " gptimes[pct50]; + print "90th percentile grace-period duration: " gptimes[pct90]; + print "99th percentile grace-period duration: " gptimes[pct99]; + print "Maximum grace-period duration: " gptimes[NR]; +}'
tools/testing/selftests/rcutorture/bin/kvm-recheck.sh +4 -1
@@ -48,7 +48,10 @@ do cat $i/Make.oldconfig.err fi parse-build.sh $i/Make.out $configfile - parse-torture.sh $i/console.log $configfile + if test "$TORTURE_SUITE" != rcuperf + then + parse-torture.sh $i/console.log $configfile + fi parse-console.sh $i/console.log $configfile if test -r $i/Warnings then
tools/testing/selftests/rcutorture/bin/kvm.sh +1 -1
@@ -156,7 +156,7 @@ do shift ;; --torture) - checkarg --torture "(suite name)" "$#" "$2" '^\(lock\|rcu\)$' '^--' + checkarg --torture "(suite name)" "$#" "$2" '^\(lock\|rcu\|rcuperf\)$' '^--' TORTURE_SUITE=$2 shift ;;
tools/testing/selftests/rcutorture/configs/rcuperf/CFLIST new file +1 -0
@@ -0,0 +1 @@ +TREE
tools/testing/selftests/rcutorture/configs/rcuperf/CFcommon new file +2 -0
@@ -0,0 +1,2 @@ +CONFIG_RCU_PERF_TEST=y +CONFIG_PRINTK_TIME=y
tools/testing/selftests/rcutorture/configs/rcuperf/TREE new file +19 -0
@@ -0,0 +1,19 @@ +CONFIG_SMP=y +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_FAST_NO_HZ=n +CONFIG_RCU_TRACE=n +CONFIG_HOTPLUG_CPU=n +CONFIG_SUSPEND=n +CONFIG_HIBERNATION=n +CONFIG_RCU_NOCB_CPU=n +CONFIG_DEBUG_LOCK_ALLOC=n +CONFIG_PROVE_LOCKING=n +CONFIG_RCU_BOOST=n +CONFIG_DEBUG_OBJECTS_RCU_HEAD=n +CONFIG_RCU_EXPERT=y
tools/testing/selftests/rcutorture/configs/rcuperf/ver_functions.sh new file +52 -0
52 lines not on this page · raw message
Signature · 1 line
2.5.2
PATCH 2/24 rcutorture: Allow for rcupdate.rcu_normal
In reply to Paul E. McKenneyCurrently, rcu_torture_writer() checks only for rcu_gp_is_expedited() when deciding whether or not to do dynamic control of RCU expediting. This means that if rcupdate.rcu_normal is specified, rcu_torture_writer() will attempt to dynamically control RCU expediting, but will nonetheless only test normal RCU grace periods. This commit therefore adds a check for !rcu_gp_is_normal(), and prints a message and desists from testing dynamic control of RCU expediting when doing so is futile.
--- kernel/rcu/rcutorture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/rcu/rcutorture.c +2 -2
@@ -916,7 +916,7 @@ rcu_torture_fqs(void *arg)static int rcu_torture_writer (void *arg) { -bool can_expedite = !rcu_gp_is_expedited (); +bool can_expedite = !rcu_gp_is_expedited () && !rcu_gp_is_normal ();int expediting =0 ;unsigned long gp_snap;bool gp_cond1 = gp_cond, gp_exp1 = gp_exp, gp_normal1 = gp_normal;
@@ -932,7 +932,7 @@ rcu_torture_writer(void *arg)VERBOSE_TOROUT_STRING ("rcu_torture_writer task started" );if (!can_expedite) {pr_alert ("%s" TORTURE_FLAG -" Grace periods expedited from boot/sysfs for %s,\n" , +" GP expediting controlled from boot/sysfs for %s,\n" , torture_type, cur_ops->name); pr_alert("%s" TORTURE_FLAG " Disabled dynamic grace-period expediting.\n",
Signature · 1 line
2.5.2
PATCH 3/24 rcutorture: Expedited-GP batch progress access to torturing
In reply to Paul E. McKenneyThis commit provides rcu_exp_batches_completed() and rcu_exp_batches_completed_sched() functions to allow torture-test modules to check how many expedited grace period batches have completed. These are analogous to the existing rcu_batches_completed(), rcu_batches_completed_bh(), and rcu_batches_completed_sched() functions.
--- include/linux/rcutiny.h | 16 ++++++++++++++++ include/linux/rcutree.h | 2 ++ kernel/rcu/tree.c | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+)
include/linux/rcutiny.h +16 -0
@@ -149,6 +149,22 @@ static inline unsigned long rcu_batches_completed_sched(void)return 0 ; } +/* +* Return the number of expedited grace periods completed. +*/ +static inline unsigned long rcu_exp_batches_completed (void ) +{ +return 0 ; +} + +/* +* Return the number of expedited sched grace periods completed. +*/ +static inline unsigned long rcu_exp_batches_completed_sched (void ) +{ +return 0 ; +} +static inline void rcu_force_quiescent_state (void ) { }
include/linux/rcutree.h +2 -0
@@ -87,6 +87,8 @@ unsigned long rcu_batches_started_sched(void);unsigned long rcu_batches_completed (void );unsigned long rcu_batches_completed_bh (void );unsigned long rcu_batches_completed_sched (void ); +unsigned long rcu_exp_batches_completed (void ); +unsigned long rcu_exp_batches_completed_sched (void );void show_rcu_gp_kthreads (void );void rcu_force_quiescent_state (void );
kernel/rcu/tree.c +22 -0
@@ -460,6 +460,28 @@ unsigned long rcu_batches_completed_bh(void)EXPORT_SYMBOL_GPL (rcu_batches_completed_bh);/* +* Return the number of RCU expedited batches completed thus far for +* debug & stats. Odd numbers mean that a batch is in progress, even +* numbers mean idle. The value returned will thus be roughly double +* the cumulative batches since boot. +*/ +unsigned long rcu_exp_batches_completed (void ) +{ +return rcu_state_p->expedited_sequence; +} +EXPORT_SYMBOL_GPL (rcu_exp_batches_completed); + +/* +* Return the number of RCU-sched expedited batches completed thus far +* for debug & stats. Similar to rcu_exp_batches_completed(). +*/ +unsigned long rcu_exp_batches_completed_sched (void ) +{ +return rcu_sched_state.expedited_sequence; +} +EXPORT_SYMBOL_GPL (rcu_exp_batches_completed_sched); + +/* * Force a quiescent state. */ void rcu_force_quiescent_state (void )
Signature · 1 line
2.5.2
PATCH 4/24 rcutorture: Add RCU grace-period performance tests
In reply to Paul E. McKenneyThis commit adds a new rcuperf module that carries out simple performance tests of RCU grace periods.
--- kernel/rcu/Makefile | 1 + kernel/rcu/rcuperf.c | 637 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/Kconfig.debug | 33 +++ 3 files changed, 671 insertions(+) create mode 100644 kernel/rcu/rcuperf.c
kernel/rcu/Makefile +1 -0
@@ -5,6 +5,7 @@ KCOV_INSTRUMENT := n obj-y += update.o sync.o obj-$(CONFIG_SRCU) += srcu.o obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o +obj-$(CONFIG_RCU_PERF_TEST) += rcuperf.o obj-$(CONFIG_TREE_RCU) += tree.o obj-$(CONFIG_PREEMPT_RCU) += tree.o obj-$(CONFIG_TREE_RCU_TRACE) += tree_trace.o
kernel/rcu/rcuperf.c new file +637 -0
637 lines not on this page · raw message
lib/Kconfig.debug +33 -0
@@ -1289,6 +1289,39 @@ config TORTURE_TEST tristate default n +config RCU_PERF_TEST + tristate "performance tests for RCU" + depends on DEBUG_KERNEL + select TORTURE_TEST + select SRCU + select TASKS_RCU + default n + help + This option provides a kernel module that runs performance + tests on the RCU infrastructure. The kernel module may be built + after the fact on the running kernel to be tested, if desired. + + Say Y here if you want RCU performance tests to be built into + the kernel. + Say M if you want the RCU performance tests to build as a module. + Say N if you are unsure. + +config RCU_PERF_TEST_RUNNABLE + bool "performance tests for RCU runnable by default" + depends on RCU_PERF_TEST = y + default n + help + This option provides a way to build the RCU performance tests + directly into the kernel without them starting up at boot time. + You can use /sys/module to manually override this setting. + This /proc file is available only when the RCU performance + tests have been built into the kernel. + + Say Y here if you want the RCU performance tests to start during + boot (you probably don't). + Say N here if you want the RCU performance tests to start only + after being manually enabled via /sys/module. + config RCU_TORTURE_TEST tristate "torture tests for RCU" depends on DEBUG_KERNEL
Signature · 1 line
2.5.2
PATCH 5/24 rcutorture: Documentation for rcuperf kernel parameters
In reply to Paul E. McKenneyThis commit adds documentation for the new rcuperf module's kernel boot parameters.
--- Documentation/kernel-parameters.txt | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
Documentation/kernel-parameters.txt +32 -0
@@ -3284,6 +3284,38 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Lazy RCU callbacks are those which RCU can prove do nothing more than free memory. + rcuperf.gp_exp= [KNL] + Measure performance of expedited synchronous + grace-period primitives. + + rcuperf.nreaders= [KNL] + Set number of RCU readers. The value -1 selects + N, where N is the number of CPUs. A value + "n" less than -1 selects N-n+1, where N is again + the number of CPUs. For example, -2 selects N + (the number of CPUs), -3 selects N+1, and so on. + A value of "n" less than or equal to -N selects + a single reader. + + rcuperf.nwriters= [KNL] + Set number of RCU writers. The values operate + the same as for rcuperf.nreaders. + N, where N is the number of CPUs + + rcuperf.perf_runnable= [BOOT] + Start rcuperf running at boot time. + + rcuperf.shutdown= [KNL] + Shut the system down after performance tests + complete. This is useful for hands-off automated + testing. + + rcuperf.perf_type= [KNL] + Specify the RCU implementation to test. + + rcuperf.verbose= [KNL] + Enable additional printk() statements. + rcutorture.cbflood_inter_holdoff= [KNL] Set holdoff time (jiffies) between successive callback-flood tests.
Signature · 1 line
2.5.2
PATCH 6/24 rcutorture: Bind rcuperf reader/writer kthreads to CPUs
In reply to Paul E. McKenneyThis commit forces more deterministic behavior by binding rcuperf's rcu_perf_reader() and rcu_perf_writer() kthreads to their respective CPUs.
--- kernel/rcu/rcuperf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/rcu/rcuperf.c +4 -1
@@ -328,8 +328,10 @@ rcu_perf_reader(void *arg) {unsigned long flags;int idx; +long me = (long )arg;VERBOSE_PERFOUT_STRING ("rcu_perf_reader task started" ); +set_cpus_allowed_ptr (current,cpumask_of (me % nr_cpu_ids));set_user_nice (current,MAX_NICE );atomic_inc (&n_rcu_perf_reader_started);
@@ -362,6 +364,7 @@ rcu_perf_writer(void *arg)WARN_ON (rcu_gp_is_expedited () && !rcu_gp_is_normal () && !gp_exp);WARN_ON (rcu_gp_is_normal () && gp_exp);WARN_ON (!wdpp); +set_cpus_allowed_ptr (current,cpumask_of (me % nr_cpu_ids)); t =ktime_get_mono_fast_ns ();if (atomic_inc_return (&n_rcu_perf_writer_started) >= nrealwriters) { t_rcu_perf_writer_started = t;
@@ -594,7 +597,7 @@ rcu_perf_init(void) goto unwind; }for (i =0 ; i < nrealreaders; i++) { - firsterr =torture_create_kthread (rcu_perf_reader,NULL , + firsterr =torture_create_kthread (rcu_perf_reader, (void *)i, reader_tasks[i]);if (firsterr) goto unwind;
Signature · 1 line
2.5.2
PATCH 7/24 rcutorture: Set rcuperf writer kthreads to real-time priority
In reply to Paul E. McKenneyThis commit forces more deterministic update-side behavior by setting rcuperf's rcu_perf_writer() kthreads to real-time priority.
--- kernel/rcu/rcuperf.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/rcu/rcuperf.c +3 -0
@@ -355,6 +355,7 @@ rcu_perf_writer(void *arg)int i =0 ;int i_max;long me = (long )arg; +struct sched_param sp;bool started = false, done = false, alldone = false;u64 t;u64 *wdp;
@@ -365,6 +366,8 @@ rcu_perf_writer(void *arg)WARN_ON (rcu_gp_is_normal () && gp_exp);WARN_ON (!wdpp);set_cpus_allowed_ptr (current,cpumask_of (me % nr_cpu_ids)); + sp.sched_priority =1 ; +sched_setscheduler_nocheck (current,SCHED_FIFO , &sp); t =ktime_get_mono_fast_ns ();if (atomic_inc_return (&n_rcu_perf_writer_started) >= nrealwriters) { t_rcu_perf_writer_started = t;
Signature · 1 line
2.5.2
PATCH 8/24 rcutorture: Print measure of batching efficiency
In reply to Paul E. McKenneyThis commit adds a line giving the number of grace periods, the number of batches, and the ratio. The larger the ratio, the greater the batching efficiency.
--- .../rcutorture/bin/kvm-recheck-rcuperf.sh | 26 +++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-)
tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf.sh +16 -10
@@ -34,33 +34,38 @@ fi configfile=`echo $i | sed -e 's/^.*\///'` -grep -e '-perf:.*writer-duration' $i/console.log | sed -e 's/^\[[^]]*]//' | +sed -e 's/^\[[^]]*]//' < $i/console.log | awk ' -{ +/-perf: .* gps: .* batches:/ { + ngps = $9; + nbatches = $11; +} + +/-perf: .*writer-duration/ { gptimes[++n] = $5 / 1000.; sum += $5 / 1000.; } END { - if (NR <= 0) { + newNR = asort(gptimes); + if (newNR <= 0) { print "No rcuperf records found???" exit; } - asort(gptimes); - pct50 = int(NR * 50 / 100); + pct50 = int(newNR * 50 / 100); if (pct50 < 1) pct50 = 1; - pct90 = int(NR * 90 / 100); + pct90 = int(newNR * 90 / 100); if (pct90 < 1) pct90 = 1; - pct99 = int(NR * 99 / 100); + pct99 = int(newNR * 99 / 100); if (pct99 < 1) pct99 = 1; div = 10 ** int(log(gptimes[pct90]) / log(10) + .5) / 100; print "Histogram bucket size: " div; last = gptimes[1] - 10; count = 0; - for (i = 1; i <= NR; i++) { + for (i = 1; i <= newNR; i++) { current = div * int(gptimes[i] / div); if (last == current) { count++;
@@ -73,10 +78,11 @@ END { } if (count > 0) print last, count; - print "Average grace-period duration: " sum / NR " microseconds"; + print "Average grace-period duration: " sum / newNR " microseconds"; print "Minimum grace-period duration: " gptimes[1]; print "50th percentile grace-period duration: " gptimes[pct50]; print "90th percentile grace-period duration: " gptimes[pct90]; print "99th percentile grace-period duration: " gptimes[pct99]; - print "Maximum grace-period duration: " gptimes[NR]; + print "Maximum grace-period duration: " gptimes[newNR]; + print "Grace periods: " ngps + 0 " Batches: " nbatches + 0 " Ratio: " ngps / nbatches; }'
Signature · 1 line
2.5.2
PATCH 9/24 rcutorture: Make rcuperf collect expedited event-trace data
In reply to Paul E. McKenneyThis commit enables ftrace in the rcuperf TREE kernel build and adds an ftrace_dump() at the end of rcuperf processing. This data will be used to measure the actual durations of the expedited grace periods without the added delays inherent in the kernel-module measurements.
--- kernel/rcu/rcuperf.c | 1 + tools/testing/selftests/rcutorture/configs/rcuperf/TREE | 1 + 2 files changed, 2 insertions(+)
kernel/rcu/rcuperf.c +1 -0
@@ -404,6 +404,7 @@ rcu_perf_writer(void *arg) perf_type, me, MIN_MEAS);if (atomic_inc_return (&n_rcu_perf_writer_finished) >= nrealwriters) { +rcu_ftrace_dump (DUMP_ALL );PERFOUT_STRING ("Test complete" ); t_rcu_perf_writer_finished = t;if (gp_exp) {
tools/testing/selftests/rcutorture/configs/rcuperf/TREE +1 -0
@@ -17,3 +17,4 @@ CONFIG_PROVE_LOCKING=n CONFIG_RCU_BOOST=n CONFIG_DEBUG_OBJECTS_RCU_HEAD=n CONFIG_RCU_EXPERT=y +CONFIG_RCU_TRACE=y
Signature · 1 line
2.5.2
PATCH 10/24 rcutorture: Make scripts analyze rcuperf trace data, if present
In reply to Paul E. McKenneyThe rcuperf event-trace data is more accurate than are the rcuperf printk()s because locking keeps things ordered. This commit therefore parses and analyzes this event-trace data if present, and falls back on the printk()s otherwise.
--- .../rcutorture/bin/kvm-recheck-rcuperf-ftrace.sh | 121 +++++++++++++++++++++ .../rcutorture/bin/kvm-recheck-rcuperf.sh | 8 ++ 2 files changed, 129 insertions(+) create mode 100755 tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf-ftrace.sh
tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf-ftrace.sh new file +121 -0
@@ -0,0 +1,121 @@ +#!/bin/bash +# +# Analyze a given results directory for rcuperf performance measurements, +# looking for ftrace data. Exits with 0 if data was found, analyzed, and +# printed. Intended to be invoked from kvm-recheck-rcuperf.sh after +# argument checking. +# +# Usage: kvm-recheck-rcuperf-ftrace.sh resdir +# +# 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, 2016 +# +# Authors: Paul E. McKenney <[email protected]> + +i="$1" +. tools/testing/selftests/rcutorture/bin/functions.sh + +if test "`grep -c 'rcu_exp_grace_period.*start' < $i/console.log`" -lt 100 +then + exit 10 +fi + +sed -e 's/^\[[^]]*]//' < $i/console.log | +grep 'us : rcu_exp_grace_period' | +sed -e 's/us : / : /' | +tr -d '\015' | +awk ' +$8 == "start" { + if (starttask != "") + nlost++; + starttask = $1; + starttime = $3; + startseq = $7; +} + +$8 == "end" { + if (starttask == $1 && startseq == $7) { + curgpdur = $3 - starttime; + gptimes[++n] = curgpdur; + gptaskcnt[starttask]++; + sum += curgpdur; + if (curgpdur > 1000) + print "Long GP " starttime "us to " $3 "us (" curgpdur "us)"; + starttask = ""; + } else { + # Lost a message or some such, reset. + starttask = ""; + nlost++; + } +} + +$8 == "done" { + piggybackcnt[$1]++; +} + +END { + newNR = asort(gptimes); + if (newNR <= 0) { + print "No ftrace records found???" + exit 10; + } + pct50 = int(newNR * 50 / 100); + if (pct50 < 1) + pct50 = 1; + pct90 = int(newNR * 90 / 100); + if (pct90 < 1) + pct90 = 1; + pct99 = int(newNR * 99 / 100); + if (pct99 < 1) + pct99 = 1; + div = 10 ** int(log(gptimes[pct90]) / log(10) + .5) / 100; + print "Histogram bucket size: " div; + last = gptimes[1] - 10; + count = 0; + for (i = 1; i <= newNR; i++) { + current = div * int(gptimes[i] / div); + if (last == current) { + count++; + } else { + if (count > 0) + print last, count; + count = 1; + last = current; + } + } + if (count > 0) + print last, count; + print "Distribution of grace periods across tasks:"; + for (i in gptaskcnt) { + print "\t" i, gptaskcnt[i]; + nbatches += gptaskcnt[i]; + } + ngps = nbatches; + print "Distribution of piggybacking across tasks:"; + for (i in piggybackcnt) { + print "\t" i, piggybackcnt[i]; + ngps += piggybackcnt[i]; + } + print "Average grace-period duration: " sum / newNR " microseconds"; + print "Minimum grace-period duration: " gptimes[1]; + print "50th percentile grace-period duration: " gptimes[pct50]; + print "90th percentile grace-period duration: " gptimes[pct90]; + print "99th percentile grace-period duration: " gptimes[pct99]; + print "Maximum grace-period duration: " gptimes[newNR]; + print "Grace periods: " ngps + 0 " Batches: " nbatches + 0 " Ratio: " ngps / nbatches " Lost: " nlost + 0; + print "Computed from ftrace data."; +}' +exit 0
tools/testing/selftests/rcutorture/bin/kvm-recheck-rcuperf.sh +8 -0
@@ -30,8 +30,15 @@ else echo Unreadable results directory: $i exit 1 fi +PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH . tools/testing/selftests/rcutorture/bin/functions.sh +if kvm-recheck-rcuperf-ftrace.sh $i +then + # ftrace data was successfully analyzed, call it good! + exit 0 +fi + configfile=`echo $i | sed -e 's/^.*\///'` sed -e 's/^\[[^]]*]//' < $i/console.log |
@@ -85,4 +92,5 @@ END { print "99th percentile grace-period duration: " gptimes[pct99]; print "Maximum grace-period duration: " gptimes[newNR]; print "Grace periods: " ngps + 0 " Batches: " nbatches + 0 " Ratio: " ngps / nbatches; + print "Computed from rcuperf printk output."; }'
Signature · 1 line
2.5.2
PATCH 11/24 rcutorture: Add rcuperf holdoff boot parameter to reduce interference
In reply to Paul E. McKenneyBoot-time activity can legitimately grab CPUs for extended time periods, so the commit adds a boot parameter to delay the start of the performance test until boot has completed. Defaults to 10 seconds.
--- Documentation/kernel-parameters.txt | 6 ++++++ kernel/rcu/rcuperf.c | 5 +++++ 2 files changed, 11 insertions(+)
Documentation/kernel-parameters.txt +6 -0
@@ -3288,6 +3288,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Measure performance of expedited synchronous grace-period primitives. + rcuperf.holdoff= [KNL] + Set test-start holdoff period. The purpose of + this parameter is to delay the start of the + test until boot completes in order to avoid + interference. + rcuperf.nreaders= [KNL] Set number of RCU readers. The value -1 selects N, where N is the number of CPUs. A value
kernel/rcu/rcuperf.c +5 -0
@@ -59,6 +59,7 @@ MODULE_AUTHOR("Paul E. McKenney <[email protected]>"); do { if (verbose) pr_alert("%s" PERF_FLAG "!!! %s\n", perf_type, s); } while (0)torture_param (bool, gp_exp, true,"Use expedited GP wait primitives" ); +torture_param (int, holdoff,10 ,"Holdoff time before test start (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, false,"Shutdown at end of performance tests." );
@@ -368,6 +369,10 @@ rcu_perf_writer(void *arg)set_cpus_allowed_ptr (current,cpumask_of (me % nr_cpu_ids)); sp.sched_priority =1 ;sched_setscheduler_nocheck (current,SCHED_FIFO , &sp); + +if (holdoff) +schedule_timeout_uninterruptible (holdoff *HZ ); + t =ktime_get_mono_fast_ns ();if (atomic_inc_return (&n_rcu_perf_writer_started) >= nrealwriters) { t_rcu_perf_writer_started = t;
Signature · 1 line
2.5.2
PATCH 12/24 rcutorture: Avoid RCU CPU stall warning and RT throttling
In reply to Paul E. McKenneyRunning rcuperf can result in RCU CPU stall warnings and RT throttling. These occur because on of the real-time writer processes does ftrace_dump() while still running at real-time priority. This commit therefore prevents these problems by setting the writer thread back to SCHED_NORMAL (AKA SCHED_OTHER) before doing ftrace_dump().
In addition, this commit adds a small fixed delay before dumping ftrace buffer in order to decrease the probability that this dumping will interfere with other writers' grace periods.
--- kernel/rcu/rcuperf.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/rcu/rcuperf.c +4 -0
@@ -404,11 +404,15 @@ rcu_perf_writer(void *arg) started = true;if (!done && i >=MIN_MEAS ) { done = true; + sp.sched_priority =0 ; +sched_setscheduler_nocheck (current, +SCHED_NORMAL , &sp);pr_alert ("%s" PERF_FLAG "rcu_perf_writer %ld has %d measurements\n" , perf_type, me,MIN_MEAS );if (atomic_inc_return (&n_rcu_perf_writer_finished) >= nrealwriters) { +schedule_timeout_interruptible (10 );rcu_ftrace_dump (DUMP_ALL );PERFOUT_STRING ("Test complete" ); t_rcu_perf_writer_finished = t;
Signature · 1 line
2.5.2
PATCH 13/24 rcutorture: Add largish-system rcuperf scenario
In reply to Paul E. McKenneyThis commit adds an rcuperf scenario named TREE54 that uses 54 CPUs and provides a four-level rcu_node combining tree.
--- .../selftests/rcutorture/configs/rcuperf/TREE54 | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tools/testing/selftests/rcutorture/configs/rcuperf/TREE54
tools/testing/selftests/rcutorture/configs/rcuperf/TREE54 new file +23 -0
@@ -0,0 +1,23 @@ +CONFIG_SMP=y +CONFIG_NR_CPUS=54 +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_FAST_NO_HZ=n +CONFIG_RCU_TRACE=n +CONFIG_HOTPLUG_CPU=n +CONFIG_SUSPEND=n +CONFIG_HIBERNATION=n +CONFIG_RCU_FANOUT=3 +CONFIG_RCU_FANOUT_LEAF=2 +CONFIG_RCU_NOCB_CPU=n +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_TRACE=y
Signature · 1 line
2.5.2
PATCH 14/24 rcuperf: Do not wake up shutdown wait queue if "shutdown" is false.
In reply to Paul E. McKenneyFrom: Artem Savkov <[email protected]>
After finishing its tests rcuperf tries to wake up shutdown_wq even if "shutdown" param is set to false, resulting in a wake_up() call on an unitialized wait_queue_head_t which leads to "BUG: spinlock bad magic" and "BUG: unable to handle kernel NULL pointer dereference".
Fix by checking "shutdown" param before waking up the queue.
--- kernel/rcu/rcuperf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
kernel/rcu/rcuperf.c +4 -2
@@ -423,8 +423,10 @@ rcu_perf_writer(void *arg) b_rcu_perf_writer_finished = cur_ops->completed (); } -smp_mb ();/* Assign before wake. */ -wake_up (&shutdown_wq); +if (shutdown) { +smp_mb ();/* Assign before wake. */ +wake_up (&shutdown_wq); + } } } if (done && !alldone &&
Signature · 1 line
2.5.2
PATCH 15/24 rcutorture: Remove redundant initialization to zero
In reply to Paul E. McKenneyThe current code initializes the global per-CPU variables rcu_torture_count and rcu_torture_batch to zero. However, C does this initialization by default, and explicit initialization of per-CPU variables now needs a different syntax if "make tags" is to work. This commit therefore removes the initialization.
--- kernel/rcu/rcutorture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/rcu/rcutorture.c +2 -2
@@ -130,8 +130,8 @@ static struct rcu_torture __rcu *rcu_torture_current;static unsigned long rcu_torture_current_version;static struct rcu_torture rcu_tortures[10 *RCU_TORTURE_PIPE_LEN ];static DEFINE_SPINLOCK (rcu_torture_lock); -static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) = { 0 }; -static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) = { 0 }; +static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count); +static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch);static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN +1 ];static atomic_t n_rcu_torture_alloc;static atomic_t n_rcu_torture_alloc_fail;
Signature · 1 line
2.5.2
PATCH 16/24 rcutorture: Consider FROZEN hotplug notifier transitions
In reply to Paul E. McKenneyFrom: Anna-Maria Gleixner <[email protected]>
The hotplug notifier rcutorture_cpu_notify() doesn't consider the corresponding CPU_XXX_FROZEN transitions. They occur on suspend/resume and are usually handled the same way as the corresponding non frozen transitions.
Mask the switch case action argument with '~CPU_TASKS_FROZEN' to map CPU_XXX_FROZEN hotplug transitions on corresponding non-frozen transitions.
--- kernel/rcu/rcutorture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/rcu/rcutorture.c +1 -1
@@ -1585,7 +1585,7 @@ static int rcutorture_cpu_notify(struct notifier_block *self, {long cpu = (long )hcpu; -switch (action) { +switch (action & ~CPU_TASKS_FROZEN ) {case CPU_ONLINE :case CPU_DOWN_FAILED : (void )rcutorture_booster_init (cpu);
Signature · 1 line
2.5.2
PATCH 17/24 torture: Clarify refusal to run more than one torture test
In reply to Paul E. McKenneyThis commit clarifies error messages -- you only get to run one torture test at a time!
--- kernel/torture.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/torture.c +2 -1
@@ -602,8 +602,9 @@ bool torture_init_begin(char *ttype, bool v, int *runnable) {mutex_lock (&fullstop_mutex);if (torture_type !=NULL ) { -pr_alert ("torture_init_begin: refusing %s init: %s running" , +pr_alert ("torture_init_begin: Refusing %s init: %s running.\n" , ttype, torture_type); +pr_alert ("torture_init_begin: One torture test at a time!\n" );mutex_unlock (&fullstop_mutex);return false; }
Signature · 1 line
2.5.2
PATCH 18/24 torture: Kill qemu, not parent process
In reply to Paul E. McKenneyThe current hang-check machinery in the rcutorture scripts uses "$!" of a parenthesized bash statement to capture the pid. Unfortunately, this captures not qemu's pid, but rather that of its parent that implements the parenthesized statement. This commit therefore adjusts things so as to capture qemu's actual pid, which then allows the script to actually kill qemu in event of a kernel hang.
--- .../selftests/rcutorture/bin/kvm-test-1-run.sh | 30 +++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-)
tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +24 -6
@@ -168,14 +168,25 @@ then fi echo "NOTE: $QEMU either did not run or was interactive" > $resdir/console.log echo $QEMU $qemu_args -m 512 -kernel $resdir/bzImage -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd -( $QEMU $qemu_args -m 512 -kernel $resdir/bzImage -append "$qemu_append $boot_args"; echo $? > $resdir/qemu-retval ) & -qemu_pid=$! +( $QEMU $qemu_args -m 512 -kernel $resdir/bzImage -append "$qemu_append $boot_args"& echo $! > $resdir/qemu_pid; wait `cat $resdir/qemu_pid`; echo $? > $resdir/qemu-retval ) & commandcompleted=0 -echo Monitoring qemu job at pid $qemu_pid +sleep 10 # Give qemu's pid a chance to reach the file +if test -s "$resdir/qemu_pid" +then + qemu_pid=`cat "$resdir/qemu_pid"` + echo Monitoring qemu job at pid $qemu_pid +else + qemu_pid="" + echo Monitoring qemu job at yet-as-unknown pid +fi while : do + if test -z "$qemu_pid" -a -s "$resdir/qemu_pid" + then + qemu_pid=`cat "$resdir/qemu_pid"` + fi kruntime=`awk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null` - if kill -0 $qemu_pid > /dev/null 2>&1 + if test -z "$qemu_pid" || kill -0 "$qemu_pid" > /dev/null 2>&1 then if test $kruntime -ge $seconds then
@@ -195,12 +206,16 @@ do ps -fp $killpid >> $resdir/Warnings 2>&1 fi else - echo ' ---' `date`: Kernel done + echo ' ---' `date`: "Kernel done" fi break fi done -if test $commandcompleted -eq 0 +if test -z "$qemu_pid" -a -s "$resdir/qemu_pid" +then + qemu_pid=`cat "$resdir/qemu_pid"` +fi +if test $commandcompleted -eq 0 -a -n "$qemu_pid" then echo Grace period for qemu job at pid $qemu_pid while :
@@ -220,6 +235,9 @@ then fi sleep 1 done +elif test -z "$qemu_pid" +then + echo Unknown PID, cannot kill qemu command fi parse-torture.sh $resdir/console.log $title
Signature · 1 line
2.5.2
PATCH 19/24 rcutorture: Convert test duration to seconds early
In reply to Paul E. McKenneyThis commit converts test duration from minutes to seconds early on in order to prepare for upcoming OS-jitter-injection changes.
--- tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh | 5 ++--- tools/testing/selftests/rcutorture/bin/kvm.sh | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-)
tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +2 -3
@@ -6,7 +6,7 @@ # Execute this in the source tree. Do not run it as a background task # because qemu does not seem to like that much. # -# Usage: kvm-test-1-run.sh config builddir resdir minutes qemu-args boot_args +# Usage: kvm-test-1-run.sh config builddir resdir seconds qemu-args boot_args # # qemu-args defaults to "-enable-kvm -soundhw pcspk -nographic", along with # arguments specifying the number of CPUs and other
@@ -123,8 +123,7 @@ while test -f $builddir.ready do sleep 1 done -minutes=$4 -seconds=$(($minutes * 60)) +seconds=$4 qemu_args=$5 boot_args=$6
tools/testing/selftests/rcutorture/bin/kvm.sh +2 -2
@@ -34,7 +34,7 @@ T=/tmp/kvm.sh.$$ trap 'rm -rf $T' 0 mkdir $T -dur=30 +dur=$((30*60)) dryrun="" KVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM PATH=${KVM}/bin:$PATH; export PATH
@@ -116,7 +116,7 @@ do ;; --duration) checkarg --duration "(minutes)" $# "$2" '^[0-9]*$' '^error' - dur=$2 + dur=$(($2*60)) shift ;; --interactive)
Signature · 1 line
2.5.2
PATCH 20/24 rcutorture: Add OS-jitter capability
In reply to Paul E. McKenneyThis commit adds a --jitter OS-jitter capability to expose bugs based on no-delay assumptions.
--- tools/testing/selftests/rcutorture/bin/jitter.sh | 83 ++++++++++++++++++++++++ tools/testing/selftests/rcutorture/bin/kvm.sh | 18 +++++ 2 files changed, 101 insertions(+) create mode 100755 tools/testing/selftests/rcutorture/bin/jitter.sh
tools/testing/selftests/rcutorture/bin/jitter.sh new file +83 -0
@@ -0,0 +1,83 @@ +#!/bin/bash +# +# Alternate sleeping and spinning on randomly selected CPUs. The purpose +# of this script is to inflict random OS jitter on a concurrently running +# test. +# +# Usage: jitter.sh me duration [ sleepmax [ spinmax ] ] +# +# me: Random-number-generator seed salt. +# duration: Time to run in seconds. +# sleepmax: Maximum microseconds to sleep, defaults to one second. +# spinmax: Maximum microseconds to spin, defaults to one millisecond. +# +# 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, 2016 +# +# Authors: Paul E. McKenney <[email protected]> + +me=$(($1 * 1000)) +duration=$2 +sleepmax=${3-1000000} +spinmax=${4-1000} + +n=1 + +starttime=`awk 'BEGIN { print systime(); }' < /dev/null` + +while : +do + # Check for done. + t=`awk -v s=$starttime 'BEGIN { print systime() - s; }' < /dev/null` + if test "$t" -gt "$duration" + then + exit 0; + fi + + # Set affinity to randomly selected CPU + cpus=`ls /sys/devices/system/cpu/*/online | + sed -e 's,/[^/]*$,,' -e 's/^[^0-9]*//' | + grep -v '^0*$'` + cpumask=`awk -v cpus="$cpus" -v me=$me -v n=$n 'BEGIN { + srand(n + me + systime()); + ncpus = split(cpus, ca); + curcpu = ca[int(rand() * ncpus + 1)]; + printf("%#x\n", lshift(1, curcpu)); + }' < /dev/null` + n=$(($n+1)) + taskset -p $cpumask $$ > /dev/null + + # Sleep a random duration + sleeptime=`awk -v me=$me -v n=$n -v sleepmax=$sleepmax 'BEGIN { + srand(n + me + systime()); + printf("%06d", int(rand() * sleepmax)); + }' < /dev/null` + n=$(($n+1)) + sleep .$sleeptime + + # Spin a random duration + limit=`awk -v me=$me -v n=$n -v spinmax=$spinmax 'BEGIN { + srand(n + me + systime()); + printf("%06d", int(rand() * spinmax)); + }' < /dev/null` + n=$(($n+1)) + for i in {1..$limit} + do + echo > /dev/null + done +done + +exit 1
tools/testing/selftests/rcutorture/bin/kvm.sh +18 -0
@@ -48,6 +48,7 @@ resdir="" configs="" cpus=0 ds=`date +%Y.%m.%d-%H:%M:%S` +jitter=0 . functions.sh
@@ -63,6 +64,7 @@ usage () { echo " --dryrun sched|script" echo " --duration minutes" echo " --interactive" + echo " --jitter N [ maxsleep (us) [ maxspin (us) ] ]" echo " --kmake-arg kernel-make-arguments" echo " --mac nn:nn:nn:nn:nn:nn" echo " --no-initrd"
@@ -122,6 +124,11 @@ do --interactive) TORTURE_QEMU_INTERACTIVE=1; export TORTURE_QEMU_INTERACTIVE ;; + --jitter) + checkarg --jitter "(# threads [ sleep [ spin ] ])" $# "$2" '^-\{,1\}[0-9]\+\( \+[0-9]\+\)\{,2\} *$' '^error$' + jitter="$2" + shift + ;; --kmake-arg) checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$' TORTURE_KMAKE_ARG="$2"
@@ -299,6 +306,7 @@ awk < $T/cfgcpu.pack \ -v CONFIGDIR="$CONFIGFRAG/" \ -v KVM="$KVM" \ -v ncpus=$cpus \ + -v jitter="$jitter" \ -v rd=$resdir/$ds/ \ -v dur=$dur \ -v TORTURE_QEMU_ARG="$TORTURE_QEMU_ARG" \
@@ -359,6 +367,16 @@ function dump(first, pastlast, batchnum) print "\techo ----", cfr[j], cpusr[j] ovf ": Starting kernel. `date` >> " rd "/log"; print "fi" } + njitter = 0; + split(jitter, ja); + if (ja[1] == -1 && ncpus == 0) + njitter = 1; + else if (ja[1] == -1) + njitter = ncpus; + else + njitter = ja[1]; + for (j = 0; j < njitter; j++) + print "jitter.sh " j " " dur " " ja[2] " " ja[3] "&" print "wait" print "if test -z \"$TORTURE_BUILDONLY\"" print "then"
Signature · 1 line
2.5.2
PATCH 21/24 rcutorture: Don't rebuild identical kernel
In reply to Paul E. McKenneyCurrently, if the user specifies multiple runs of a given test configuration, the scripting does multiple kernel builds. This wastes both time and disk space, so this commit makes the scripting use the first build for all runs of a given test configuration.
--- .../selftests/rcutorture/bin/kvm-test-1-run.sh | 26 ++++++++++++++++------ 1 file changed, 19 insertions(+), 7 deletions(-)
tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +19 -7
@@ -91,25 +91,33 @@ fi # CONFIG_PCMCIA=n # CONFIG_CARDBUS=n # CONFIG_YENTA=n -if kvm-build.sh $config_template $builddir $T +base_resdir=`echo $resdir | sed -e 's/\.[0-9]\+$//'` +if test "$base_resdir" != "$resdir" -a -f $base_resdir/bzImage -a -f $base_resdir/vmlinux then + # Rerunning previous test, so use that test's kernel. + QEMU="`identify_qemu $base_resdir/vmlinux`" + KERNEL=$base_resdir/bzImage + ln -s $base_resdir/Make*.out $resdir # for kvm-recheck.sh + ln -s $base_resdir/.config $resdir # for kvm-recheck.sh +elif kvm-build.sh $config_template $builddir $T +then + # Had to build a kernel for this test. QEMU="`identify_qemu $builddir/vmlinux`" BOOT_IMAGE="`identify_boot_image $QEMU`" cp $builddir/Make*.out $resdir + cp $builddir/vmlinux $resdir cp $builddir/.config $resdir if test -n "$BOOT_IMAGE" then cp $builddir/$BOOT_IMAGE $resdir + KERNEL=$resdir/bzImage else echo No identifiable boot image, not running KVM, see $resdir. echo Do the torture scripts know about your architecture? fi parse-build.sh $resdir/Make.out $title - if test -f $builddir.wait - then - mv $builddir.wait $builddir.ready - fi else + # Build failed. cp $builddir/Make*.out $resdir cp $builddir/.config $resdir || : echo Build failed, not running KVM, see $resdir.
@@ -119,6 +127,10 @@ else fi exit 1 fi +if test -f $builddir.wait +then + mv $builddir.wait $builddir.ready +fi while test -f $builddir.ready do sleep 1
@@ -166,8 +178,8 @@ then exit 0 fi echo "NOTE: $QEMU either did not run or was interactive" > $resdir/console.log -echo $QEMU $qemu_args -m 512 -kernel $resdir/bzImage -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd -( $QEMU $qemu_args -m 512 -kernel $resdir/bzImage -append "$qemu_append $boot_args"& echo $! > $resdir/qemu_pid; wait `cat $resdir/qemu_pid`; echo $? > $resdir/qemu-retval ) & +echo $QEMU $qemu_args -m 512 -kernel $KERNEL -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd +( $QEMU $qemu_args -m 512 -kernel $KERNEL -append "$qemu_append $boot_args"& echo $! > $resdir/qemu_pid; wait `cat $resdir/qemu_pid`; echo $? > $resdir/qemu-retval ) & commandcompleted=0 sleep 10 # Give qemu's pid a chance to reach the file if test -s "$resdir/qemu_pid"
Signature · 1 line
2.5.2
PATCH 22/24 rcutorture: Dump trace buffer upon shutdown
In reply to Paul E. McKenneyWhen running from the scripts, rcutorture is completely headless, so there is no way to to manually dump the trace buffer. This commit therefore unconditionally dumps the trace buffer upon timed shutdown. However, if you are using rmmod to end the test, it is still up to you to manually dump the trace buffer.
--- kernel/torture.c | 1 + 1 file changed, 1 insertion(+)
kernel/torture.c +1 -0
@@ -451,6 +451,7 @@ static int torture_shutdown(void *arg)torture_shutdown_hook (); else VERBOSE_TOROUT_STRING("No torture_shutdown_hook(), skipping."); +ftrace_dump (DUMP_ALL );kernel_power_off ();/* Shut down the system. */ return 0 ; }
Signature · 1 line
2.5.2
PATCH 23/24 rcutorture: Add irqs-disabled test for call_rcu()
In reply to Paul E. McKenneyMutation testing carried out by Iftekhar Ahmed of Oregon State University showed that rcutorture is failing to test invocations of call_rcu() having interrupts disabled. This commit therefore adds interrupt disabling around one of the existing invocations of call_rcu() (and friends).
--- kernel/rcu/rcutorture.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/rcu/rcutorture.c +2 -0
@@ -1478,7 +1478,9 @@ static int rcu_torture_barrier_cbs(void *arg)* The above smp_load_acquire() ensures barrier_phase load * is ordered before the folloiwng ->call(). */ +local_irq_disable ();/* Just to test no-irq call_rcu(). */ cur_ops->call (&rcu, rcu_torture_barrier_cbf); +local_irq_enable ();if (atomic_dec_and_test (&barrier_cbs_count))wake_up (&barrier_wq); }while (!torture_must_stop ());
Signature · 1 line
2.5.2
PATCH 24/24 rcutorture: Add boot-time adjustment of leaf fanout
In reply to Paul E. McKenneyCurrently, the rcutorture scripts do not test boot-time adjustment of leaf fanout (via the rcutree.rcu_fanout_leaf boot parameter), as was noted during testing carried out by Iftekhar Ahmed of Oregon State University. This commit therefore adjusts TREE04's CONFIG_RCU_FANOUT_LEAF from 4 to 3, and also adds rcutree.rcu_fanout_leaf=4 to its boot parameters. This change forces RCU's boot-time geometry-change code to be exercised.
--- tools/testing/selftests/rcutorture/configs/rcu/TREE04 | 2 +- tools/testing/selftests/rcutorture/configs/rcu/TREE04.boot | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/rcutorture/configs/rcu/TREE04 +1 -1
@@ -14,7 +14,7 @@ CONFIG_HOTPLUG_CPU=n CONFIG_SUSPEND=n CONFIG_HIBERNATION=n CONFIG_RCU_FANOUT=4 -CONFIG_RCU_FANOUT_LEAF=4 +CONFIG_RCU_FANOUT_LEAF=3 CONFIG_RCU_NOCB_CPU=n CONFIG_DEBUG_LOCK_ALLOC=n CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
tools/testing/selftests/rcutorture/configs/rcu/TREE04.boot +1 -1
@@ -1 +1 @@ -rcutorture.torture_type=rcu_bh +rcutorture.torture_type=rcu_bh rcutree.rcu_fanout_leaf=4
Signature · 1 line
2.5.2