diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2016-03-29 17:22:26 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2016-04-21 16:45:35 -0400 |
commit | 6e524a603f0b72281019e4ec29b1022388f9f231 (patch) | |
tree | d2d383b3fcc1234153288d080a4e2281bd47bdb1 | |
parent | 480b1eb659f65be8ed039f1a9db3f762c41c9770 (diff) |
rcutorture: Add OS-jitter capability
This commit adds a --jitter OS-jitter capability to expose bugs based
on no-delay assumptions.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rwxr-xr-x | tools/testing/selftests/rcutorture/bin/jitter.sh | 90 | ||||
-rwxr-xr-x | tools/testing/selftests/rcutorture/bin/kvm.sh | 18 |
2 files changed, 108 insertions, 0 deletions
diff --git a/tools/testing/selftests/rcutorture/bin/jitter.sh b/tools/testing/selftests/rcutorture/bin/jitter.sh new file mode 100755 index 000000000000..3633828375e3 --- /dev/null +++ b/tools/testing/selftests/rcutorture/bin/jitter.sh | |||
@@ -0,0 +1,90 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # Alternate sleeping and spinning on randomly selected CPUs. The purpose | ||
4 | # of this script is to inflict random OS jitter on a concurrently running | ||
5 | # test. | ||
6 | # | ||
7 | # Usage: jitter.sh me duration [ sleepmax [ spinmax ] ] | ||
8 | # | ||
9 | # me: Random-number-generator seed salt. | ||
10 | # duration: Time to run in seconds. | ||
11 | # sleepmax: Maximum microseconds to sleep, defaults to one second. | ||
12 | # spinmax: Maximum microseconds to spin, defaults to one millisecond. | ||
13 | # | ||
14 | # This program is free software; you can redistribute it and/or modify | ||
15 | # it under the terms of the GNU General Public License as published by | ||
16 | # the Free Software Foundation; either version 2 of the License, or | ||
17 | # (at your option) any later version. | ||
18 | # | ||
19 | # This program is distributed in the hope that it will be useful, | ||
20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | # GNU General Public License for more details. | ||
23 | # | ||
24 | # You should have received a copy of the GNU General Public License | ||
25 | # along with this program; if not, you can access it online at | ||
26 | # http://www.gnu.org/licenses/gpl-2.0.html. | ||
27 | # | ||
28 | # Copyright (C) IBM Corporation, 2016 | ||
29 | # | ||
30 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | ||
31 | |||
32 | me=$(($1 * 1000)) | ||
33 | duration=$2 | ||
34 | sleepmax=${3-1000000} | ||
35 | spinmax=${4-1000} | ||
36 | |||
37 | n=1 | ||
38 | |||
39 | starttime=`awk 'BEGIN { print systime(); }' < /dev/null` | ||
40 | |||
41 | while : | ||
42 | do | ||
43 | # Check for done. | ||
44 | t=`awk -v s=$starttime 'BEGIN { print systime() - s; }' < /dev/null` | ||
45 | if test "$t" -gt "$duration" | ||
46 | then | ||
47 | exit 0; | ||
48 | fi | ||
49 | |||
50 | # Set affinity to randomly selected CPU | ||
51 | cpus=`ls /sys/devices/system/cpu/*/online | | ||
52 | sed -e 's,/[^/]*$,,' -e 's/^[^0-9]*//' | | ||
53 | grep -v '^0*$'` | ||
54 | cpumask=`awk -v cpus="$cpus" -v me=$me -v n=$n 'BEGIN { | ||
55 | srand(n + me + systime()); | ||
56 | ncpus = split(cpus, ca); | ||
57 | curcpu = ca[int(rand() * ncpus + 1)]; | ||
58 | mask = lshift(1, curcpu); | ||
59 | if (mask + 0 <= 0) | ||
60 | mask = 1; | ||
61 | printf("%#x\n", mask); | ||
62 | }' < /dev/null` | ||
63 | n=$(($n+1)) | ||
64 | if ! taskset -p $cpumask $$ > /dev/null 2>&1 | ||
65 | then | ||
66 | echo taskset failure: '"taskset -p ' $cpumask $$ '"' | ||
67 | exit 1 | ||
68 | fi | ||
69 | |||
70 | # Sleep a random duration | ||
71 | sleeptime=`awk -v me=$me -v n=$n -v sleepmax=$sleepmax 'BEGIN { | ||
72 | srand(n + me + systime()); | ||
73 | printf("%06d", int(rand() * sleepmax)); | ||
74 | }' < /dev/null` | ||
75 | n=$(($n+1)) | ||
76 | sleep .$sleeptime | ||
77 | |||
78 | # Spin a random duration | ||
79 | limit=`awk -v me=$me -v n=$n -v spinmax=$spinmax 'BEGIN { | ||
80 | srand(n + me + systime()); | ||
81 | printf("%06d", int(rand() * spinmax)); | ||
82 | }' < /dev/null` | ||
83 | n=$(($n+1)) | ||
84 | for i in {1..$limit} | ||
85 | do | ||
86 | echo > /dev/null | ||
87 | done | ||
88 | done | ||
89 | |||
90 | exit 1 | ||
diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh index 704e219f67a7..0d598145873e 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm.sh | |||
@@ -48,6 +48,7 @@ resdir="" | |||
48 | configs="" | 48 | configs="" |
49 | cpus=0 | 49 | cpus=0 |
50 | ds=`date +%Y.%m.%d-%H:%M:%S` | 50 | ds=`date +%Y.%m.%d-%H:%M:%S` |
51 | jitter=0 | ||
51 | 52 | ||
52 | . functions.sh | 53 | . functions.sh |
53 | 54 | ||
@@ -63,6 +64,7 @@ usage () { | |||
63 | echo " --dryrun sched|script" | 64 | echo " --dryrun sched|script" |
64 | echo " --duration minutes" | 65 | echo " --duration minutes" |
65 | echo " --interactive" | 66 | echo " --interactive" |
67 | echo " --jitter N [ maxsleep (us) [ maxspin (us) ] ]" | ||
66 | echo " --kmake-arg kernel-make-arguments" | 68 | echo " --kmake-arg kernel-make-arguments" |
67 | echo " --mac nn:nn:nn:nn:nn:nn" | 69 | echo " --mac nn:nn:nn:nn:nn:nn" |
68 | echo " --no-initrd" | 70 | echo " --no-initrd" |
@@ -122,6 +124,11 @@ do | |||
122 | --interactive) | 124 | --interactive) |
123 | TORTURE_QEMU_INTERACTIVE=1; export TORTURE_QEMU_INTERACTIVE | 125 | TORTURE_QEMU_INTERACTIVE=1; export TORTURE_QEMU_INTERACTIVE |
124 | ;; | 126 | ;; |
127 | --jitter) | ||
128 | checkarg --jitter "(# threads [ sleep [ spin ] ])" $# "$2" '^-\{,1\}[0-9]\+\( \+[0-9]\+\)\{,2\} *$' '^error$' | ||
129 | jitter="$2" | ||
130 | shift | ||
131 | ;; | ||
125 | --kmake-arg) | 132 | --kmake-arg) |
126 | checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$' | 133 | checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$' |
127 | TORTURE_KMAKE_ARG="$2" | 134 | TORTURE_KMAKE_ARG="$2" |
@@ -299,6 +306,7 @@ awk < $T/cfgcpu.pack \ | |||
299 | -v CONFIGDIR="$CONFIGFRAG/" \ | 306 | -v CONFIGDIR="$CONFIGFRAG/" \ |
300 | -v KVM="$KVM" \ | 307 | -v KVM="$KVM" \ |
301 | -v ncpus=$cpus \ | 308 | -v ncpus=$cpus \ |
309 | -v jitter="$jitter" \ | ||
302 | -v rd=$resdir/$ds/ \ | 310 | -v rd=$resdir/$ds/ \ |
303 | -v dur=$dur \ | 311 | -v dur=$dur \ |
304 | -v TORTURE_QEMU_ARG="$TORTURE_QEMU_ARG" \ | 312 | -v TORTURE_QEMU_ARG="$TORTURE_QEMU_ARG" \ |
@@ -359,6 +367,16 @@ function dump(first, pastlast, batchnum) | |||
359 | print "\techo ----", cfr[j], cpusr[j] ovf ": Starting kernel. `date` >> " rd "/log"; | 367 | print "\techo ----", cfr[j], cpusr[j] ovf ": Starting kernel. `date` >> " rd "/log"; |
360 | print "fi" | 368 | print "fi" |
361 | } | 369 | } |
370 | njitter = 0; | ||
371 | split(jitter, ja); | ||
372 | if (ja[1] == -1 && ncpus == 0) | ||
373 | njitter = 1; | ||
374 | else if (ja[1] == -1) | ||
375 | njitter = ncpus; | ||
376 | else | ||
377 | njitter = ja[1]; | ||
378 | for (j = 0; j < njitter; j++) | ||
379 | print "jitter.sh " j " " dur " " ja[2] " " ja[3] "&" | ||
362 | print "wait" | 380 | print "wait" |
363 | print "if test -z \"$TORTURE_BUILDONLY\"" | 381 | print "if test -z \"$TORTURE_BUILDONLY\"" |
364 | print "then" | 382 | print "then" |