Commit 6e524a60 authored by Paul E. McKenney's avatar Paul E. McKenney

rcutorture: Add OS-jitter capability

This commit adds a --jitter OS-jitter capability to expose bugs based
on no-delay assumptions.
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent 480b1eb6
#!/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 <paulmck@linux.vnet.ibm.com>
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)];
mask = lshift(1, curcpu);
if (mask + 0 <= 0)
mask = 1;
printf("%#x\n", mask);
}' < /dev/null`
n=$(($n+1))
if ! taskset -p $cpumask $$ > /dev/null 2>&1
then
echo taskset failure: '"taskset -p ' $cpumask $$ '"'
exit 1
fi
# 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
...@@ -48,6 +48,7 @@ resdir="" ...@@ -48,6 +48,7 @@ resdir=""
configs="" configs=""
cpus=0 cpus=0
ds=`date +%Y.%m.%d-%H:%M:%S` ds=`date +%Y.%m.%d-%H:%M:%S`
jitter=0
. functions.sh . functions.sh
...@@ -63,6 +64,7 @@ usage () { ...@@ -63,6 +64,7 @@ usage () {
echo " --dryrun sched|script" echo " --dryrun sched|script"
echo " --duration minutes" echo " --duration minutes"
echo " --interactive" echo " --interactive"
echo " --jitter N [ maxsleep (us) [ maxspin (us) ] ]"
echo " --kmake-arg kernel-make-arguments" echo " --kmake-arg kernel-make-arguments"
echo " --mac nn:nn:nn:nn:nn:nn" echo " --mac nn:nn:nn:nn:nn:nn"
echo " --no-initrd" echo " --no-initrd"
...@@ -122,6 +124,11 @@ do ...@@ -122,6 +124,11 @@ do
--interactive) --interactive)
TORTURE_QEMU_INTERACTIVE=1; export TORTURE_QEMU_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) --kmake-arg)
checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$' checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$'
TORTURE_KMAKE_ARG="$2" TORTURE_KMAKE_ARG="$2"
...@@ -299,6 +306,7 @@ awk < $T/cfgcpu.pack \ ...@@ -299,6 +306,7 @@ awk < $T/cfgcpu.pack \
-v CONFIGDIR="$CONFIGFRAG/" \ -v CONFIGDIR="$CONFIGFRAG/" \
-v KVM="$KVM" \ -v KVM="$KVM" \
-v ncpus=$cpus \ -v ncpus=$cpus \
-v jitter="$jitter" \
-v rd=$resdir/$ds/ \ -v rd=$resdir/$ds/ \
-v dur=$dur \ -v dur=$dur \
-v TORTURE_QEMU_ARG="$TORTURE_QEMU_ARG" \ -v TORTURE_QEMU_ARG="$TORTURE_QEMU_ARG" \
...@@ -359,6 +367,16 @@ function dump(first, pastlast, batchnum) ...@@ -359,6 +367,16 @@ function dump(first, pastlast, batchnum)
print "\techo ----", cfr[j], cpusr[j] ovf ": Starting kernel. `date` >> " rd "/log"; print "\techo ----", cfr[j], cpusr[j] ovf ": Starting kernel. `date` >> " rd "/log";
print "fi" 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 "wait"
print "if test -z \"$TORTURE_BUILDONLY\"" print "if test -z \"$TORTURE_BUILDONLY\""
print "then" print "then"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment