]> git.karo-electronics.de Git - linux-beck.git/commitdiff
rcutorture: Add OS-jitter capability
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Tue, 29 Mar 2016 21:22:26 +0000 (14:22 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Thu, 21 Apr 2016 20:45:35 +0000 (13:45 -0700)
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>
tools/testing/selftests/rcutorture/bin/jitter.sh [new file with mode: 0755]
tools/testing/selftests/rcutorture/bin/kvm.sh

diff --git a/tools/testing/selftests/rcutorture/bin/jitter.sh b/tools/testing/selftests/rcutorture/bin/jitter.sh
new file mode 100755 (executable)
index 0000000..3633828
--- /dev/null
@@ -0,0 +1,90 @@
+#!/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
index 704e219f67a7a0f0f587af0e9e50eee7848fec78..0d598145873e898d388b6e5d411ddc9b4c937897 100755 (executable)
@@ -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"