mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00

On a 8-socket server the TSC is wrongly marked as 'unstable' and disabled during boot time on about one out of 120 boot attempts: clocksource: timekeeping watchdog on CPU227: wd-tsc-wd excessive read-back delay of 153560ns vs. limit of 125000ns, wd-wd read-back delay only 11440ns, attempt 3, marking tsc unstable tsc: Marking TSC unstable due to clocksource watchdog TSC found unstable after boot, most likely due to broken BIOS. Use 'tsc=unstable'. sched_clock: Marking unstable (119294969739, 159204297)<-(125446229205, -5992055152) clocksource: Checking clocksource tsc synchronization from CPU 319 to CPUs 0,99,136,180,210,542,601,896. clocksource: Switched to clocksource hpet The reason is that for platform with a large number of CPUs, there are sporadic big or huge read latencies while reading the watchog/clocksource during boot or when system is under stress work load, and the frequency and maximum value of the latency goes up with the number of online CPUs. The cCurrent code already has logic to detect and filter such high latency case by reading the watchdog twice and checking the two deltas. Due to the randomness of the latency, there is a low probabilty that the first delta (latency) is big, but the second delta is small and looks valid. The watchdog code retries the readouts by default twice, which is not necessarily sufficient for systems with a large number of CPUs. There is a command line parameter 'max_cswd_read_retries' which allows to increase the number of retries, but that's not user friendly as it needs to be tweaked per system. As the number of required retries is proportional to the number of online CPUs, this parameter can be calculated at runtime. Scale and enlarge the number of retries according to the number of online CPUs and remove the command line parameter completely. [ tglx: Massaged change log and comments ] Signed-off-by: Feng Tang <feng.tang@intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Jin Wang <jin1.wang@intel.com> Tested-by: Paul E. McKenney <paulmck@kernel.org> Reviewed-by: Waiman Long <longman@redhat.com> Reviewed-by: Paul E. McKenney <paulmck@kernel.org> Link: https://lore.kernel.org/r/20240221060859.1027450-1-feng.tang@intel.com
695 lines
23 KiB
Bash
Executable file
695 lines
23 KiB
Bash
Executable file
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0+
|
|
#
|
|
# Run a series of torture tests, intended for overnight or
|
|
# longer timeframes, and also for large systems.
|
|
#
|
|
# Usage: torture.sh [ options ]
|
|
#
|
|
# Copyright (C) 2020 Facebook, Inc.
|
|
#
|
|
# Authors: Paul E. McKenney <paulmck@kernel.org>
|
|
|
|
scriptname=$0
|
|
args="$*"
|
|
|
|
RCUTORTURE="`pwd`/tools/testing/selftests/rcutorture"; export RCUTORTURE
|
|
PATH=${RCUTORTURE}/bin:$PATH; export PATH
|
|
. functions.sh
|
|
|
|
TORTURE_ALLOTED_CPUS="`identify_qemu_vcpus`"
|
|
MAKE_ALLOTED_CPUS=$((TORTURE_ALLOTED_CPUS*2))
|
|
HALF_ALLOTED_CPUS=$((TORTURE_ALLOTED_CPUS/2))
|
|
if test "$HALF_ALLOTED_CPUS" -lt 1
|
|
then
|
|
HALF_ALLOTED_CPUS=1
|
|
fi
|
|
VERBOSE_BATCH_CPUS=$((TORTURE_ALLOTED_CPUS/16))
|
|
if test "$VERBOSE_BATCH_CPUS" -lt 2
|
|
then
|
|
VERBOSE_BATCH_CPUS=0
|
|
fi
|
|
|
|
# Configurations/scenarios.
|
|
configs_rcutorture=
|
|
configs_locktorture=
|
|
configs_scftorture=
|
|
kcsan_kmake_args=
|
|
|
|
# Default compression, duration, and apportionment.
|
|
compress_concurrency="`identify_qemu_vcpus`"
|
|
duration_base=10
|
|
duration_rcutorture_frac=7
|
|
duration_locktorture_frac=1
|
|
duration_scftorture_frac=2
|
|
|
|
# "yes" or "no" parameters
|
|
do_allmodconfig=yes
|
|
do_rcutorture=yes
|
|
do_locktorture=yes
|
|
do_scftorture=yes
|
|
do_rcuscale=yes
|
|
do_refscale=yes
|
|
do_kvfree=yes
|
|
do_kasan=yes
|
|
do_kcsan=no
|
|
do_clocksourcewd=yes
|
|
do_rt=yes
|
|
do_rcutasksflavors=yes
|
|
do_srcu_lockdep=yes
|
|
|
|
# doyesno - Helper function for yes/no arguments
|
|
function doyesno () {
|
|
if test "$1" = "$2"
|
|
then
|
|
echo yes
|
|
else
|
|
echo no
|
|
fi
|
|
}
|
|
|
|
usage () {
|
|
echo "Usage: $scriptname optional arguments:"
|
|
echo " --compress-concurrency concurrency"
|
|
echo " --configs-rcutorture \"config-file list w/ repeat factor (3*TINY01)\""
|
|
echo " --configs-locktorture \"config-file list w/ repeat factor (10*LOCK01)\""
|
|
echo " --configs-scftorture \"config-file list w/ repeat factor (2*CFLIST)\""
|
|
echo " --do-all"
|
|
echo " --do-allmodconfig / --do-no-allmodconfig / --no-allmodconfig"
|
|
echo " --do-clocksourcewd / --do-no-clocksourcewd / --no-clocksourcewd"
|
|
echo " --do-kasan / --do-no-kasan / --no-kasan"
|
|
echo " --do-kcsan / --do-no-kcsan / --no-kcsan"
|
|
echo " --do-kvfree / --do-no-kvfree / --no-kvfree"
|
|
echo " --do-locktorture / --do-no-locktorture / --no-locktorture"
|
|
echo " --do-none"
|
|
echo " --do-rcuscale / --do-no-rcuscale / --no-rcuscale"
|
|
echo " --do-rcutasksflavors / --do-no-rcutasksflavors / --no-rcutasksflavors"
|
|
echo " --do-rcutorture / --do-no-rcutorture / --no-rcutorture"
|
|
echo " --do-refscale / --do-no-refscale / --no-refscale"
|
|
echo " --do-rt / --do-no-rt / --no-rt"
|
|
echo " --do-scftorture / --do-no-scftorture / --no-scftorture"
|
|
echo " --do-srcu-lockdep / --do-no-srcu-lockdep / --no-srcu-lockdep"
|
|
echo " --duration [ <minutes> | <hours>h | <days>d ]"
|
|
echo " --kcsan-kmake-arg kernel-make-arguments"
|
|
exit 1
|
|
}
|
|
|
|
while test $# -gt 0
|
|
do
|
|
case "$1" in
|
|
--compress-concurrency)
|
|
checkarg --compress-concurrency "(concurrency level)" $# "$2" '^[0-9][0-9]*$' '^error'
|
|
compress_concurrency=$2
|
|
shift
|
|
;;
|
|
--config-rcutorture|--configs-rcutorture)
|
|
checkarg --configs-rcutorture "(list of config files)" "$#" "$2" '^[^/]\+$' '^--'
|
|
configs_rcutorture="$configs_rcutorture $2"
|
|
shift
|
|
;;
|
|
--config-locktorture|--configs-locktorture)
|
|
checkarg --configs-locktorture "(list of config files)" "$#" "$2" '^[^/]\+$' '^--'
|
|
configs_locktorture="$configs_locktorture $2"
|
|
shift
|
|
;;
|
|
--config-scftorture|--configs-scftorture)
|
|
checkarg --configs-scftorture "(list of config files)" "$#" "$2" '^[^/]\+$' '^--'
|
|
configs_scftorture="$configs_scftorture $2"
|
|
shift
|
|
;;
|
|
--do-all|--doall)
|
|
do_allmodconfig=yes
|
|
do_rcutasksflavor=yes
|
|
do_rcutorture=yes
|
|
do_locktorture=yes
|
|
do_scftorture=yes
|
|
do_rcuscale=yes
|
|
do_refscale=yes
|
|
do_rt=yes
|
|
do_kvfree=yes
|
|
do_kasan=yes
|
|
do_kcsan=yes
|
|
do_clocksourcewd=yes
|
|
do_srcu_lockdep=yes
|
|
;;
|
|
--do-allmodconfig|--do-no-allmodconfig|--no-allmodconfig)
|
|
do_allmodconfig=`doyesno "$1" --do-allmodconfig`
|
|
;;
|
|
--do-clocksourcewd|--do-no-clocksourcewd|--no-clocksourcewd)
|
|
do_clocksourcewd=`doyesno "$1" --do-clocksourcewd`
|
|
;;
|
|
--do-kasan|--do-no-kasan|--no-kasan)
|
|
do_kasan=`doyesno "$1" --do-kasan`
|
|
;;
|
|
--do-kcsan|--do-no-kcsan|--no-kcsan)
|
|
do_kcsan=`doyesno "$1" --do-kcsan`
|
|
;;
|
|
--do-kvfree|--do-no-kvfree|--no-kvfree)
|
|
do_kvfree=`doyesno "$1" --do-kvfree`
|
|
;;
|
|
--do-locktorture|--do-no-locktorture|--no-locktorture)
|
|
do_locktorture=`doyesno "$1" --do-locktorture`
|
|
;;
|
|
--do-none|--donone)
|
|
do_allmodconfig=no
|
|
do_rcutasksflavors=no
|
|
do_rcutorture=no
|
|
do_locktorture=no
|
|
do_scftorture=no
|
|
do_rcuscale=no
|
|
do_refscale=no
|
|
do_rt=no
|
|
do_kvfree=no
|
|
do_kasan=no
|
|
do_kcsan=no
|
|
do_clocksourcewd=no
|
|
do_srcu_lockdep=no
|
|
;;
|
|
--do-rcuscale|--do-no-rcuscale|--no-rcuscale)
|
|
do_rcuscale=`doyesno "$1" --do-rcuscale`
|
|
;;
|
|
--do-rcutasksflavors|--do-no-rcutasksflavors|--no-rcutasksflavors)
|
|
do_rcutasksflavors=`doyesno "$1" --do-rcutasksflavors`
|
|
;;
|
|
--do-rcutorture|--do-no-rcutorture|--no-rcutorture)
|
|
do_rcutorture=`doyesno "$1" --do-rcutorture`
|
|
;;
|
|
--do-refscale|--do-no-refscale|--no-refscale)
|
|
do_refscale=`doyesno "$1" --do-refscale`
|
|
;;
|
|
--do-rt|--do-no-rt|--no-rt)
|
|
do_rt=`doyesno "$1" --do-rt`
|
|
;;
|
|
--do-scftorture|--do-no-scftorture|--no-scftorture)
|
|
do_scftorture=`doyesno "$1" --do-scftorture`
|
|
;;
|
|
--do-srcu-lockdep|--do-no-srcu-lockdep|--no-srcu-lockdep)
|
|
do_srcu_lockdep=`doyesno "$1" --do-srcu-lockdep`
|
|
;;
|
|
--duration)
|
|
checkarg --duration "(minutes)" $# "$2" '^[0-9][0-9]*\(m\|h\|d\|\)$' '^error'
|
|
mult=1
|
|
if echo "$2" | grep -q 'm$'
|
|
then
|
|
mult=1
|
|
elif echo "$2" | grep -q 'h$'
|
|
then
|
|
mult=60
|
|
elif echo "$2" | grep -q 'd$'
|
|
then
|
|
mult=1440
|
|
fi
|
|
ts=`echo $2 | sed -e 's/[smhd]$//'`
|
|
duration_base=$(($ts*mult))
|
|
shift
|
|
;;
|
|
--kcsan-kmake-arg|--kcsan-kmake-args)
|
|
checkarg --kcsan-kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$'
|
|
kcsan_kmake_args="`echo "$kcsan_kmake_args $2" | sed -e 's/^ *//' -e 's/ *$//'`"
|
|
shift
|
|
;;
|
|
*)
|
|
echo Unknown argument $1
|
|
usage
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
ds="`date +%Y.%m.%d-%H.%M.%S`-torture"
|
|
startdate="`date`"
|
|
starttime="`get_starttime`"
|
|
|
|
T="`mktemp -d ${TMPDIR-/tmp}/torture.sh.XXXXXX`"
|
|
trap 'rm -rf $T' 0 2
|
|
|
|
echo " --- " $scriptname $args | tee -a $T/log
|
|
echo " --- Results directory: " $ds | tee -a $T/log
|
|
|
|
# Calculate rcutorture defaults and apportion time
|
|
if test -z "$configs_rcutorture"
|
|
then
|
|
configs_rcutorture=CFLIST
|
|
fi
|
|
duration_rcutorture=$((duration_base*duration_rcutorture_frac/10))
|
|
if test "$duration_rcutorture" -eq 0
|
|
then
|
|
echo " --- Zero time for rcutorture, disabling" | tee -a $T/log
|
|
do_rcutorture=no
|
|
fi
|
|
|
|
# Calculate locktorture defaults and apportion time
|
|
if test -z "$configs_locktorture"
|
|
then
|
|
configs_locktorture=CFLIST
|
|
fi
|
|
duration_locktorture=$((duration_base*duration_locktorture_frac/10))
|
|
if test "$duration_locktorture" -eq 0
|
|
then
|
|
echo " --- Zero time for locktorture, disabling" | tee -a $T/log
|
|
do_locktorture=no
|
|
fi
|
|
|
|
# Calculate scftorture defaults and apportion time
|
|
if test -z "$configs_scftorture"
|
|
then
|
|
configs_scftorture=CFLIST
|
|
fi
|
|
duration_scftorture=$((duration_base*duration_scftorture_frac/10))
|
|
if test "$duration_scftorture" -eq 0
|
|
then
|
|
echo " --- Zero time for scftorture, disabling" | tee -a $T/log
|
|
do_scftorture=no
|
|
fi
|
|
|
|
touch $T/failures
|
|
touch $T/successes
|
|
|
|
# torture_one - Does a single kvm.sh run.
|
|
#
|
|
# Usage:
|
|
# torture_bootargs="[ kernel boot arguments ]"
|
|
# torture_one flavor [ kvm.sh arguments ]
|
|
#
|
|
# Note that "flavor" is an arbitrary string. Supply --torture if needed.
|
|
# Note that quoting is problematic. So on the command line, pass multiple
|
|
# values with multiple kvm.sh argument instances.
|
|
function torture_one {
|
|
local cur_bootargs=
|
|
local boottag=
|
|
|
|
echo " --- $curflavor:" Start `date` | tee -a $T/log
|
|
if test -n "$torture_bootargs"
|
|
then
|
|
boottag="--bootargs"
|
|
cur_bootargs="$torture_bootargs"
|
|
fi
|
|
"$@" $boottag "$cur_bootargs" --datestamp "$ds/results-$curflavor" > $T/$curflavor.out 2>&1
|
|
retcode=$?
|
|
resdir="`grep '^Results directory: ' $T/$curflavor.out | tail -1 | sed -e 's/^Results directory: //'`"
|
|
if test -z "$resdir"
|
|
then
|
|
cat $T/$curflavor.out | tee -a $T/log
|
|
echo retcode=$retcode | tee -a $T/log
|
|
else
|
|
echo $resdir > $T/last-resdir
|
|
fi
|
|
if test "$retcode" == 0
|
|
then
|
|
echo "$curflavor($retcode)" $resdir >> $T/successes
|
|
else
|
|
echo "$curflavor($retcode)" $resdir >> $T/failures
|
|
fi
|
|
}
|
|
|
|
# torture_set - Does a set of tortures with and without KASAN and KCSAN.
|
|
#
|
|
# Usage:
|
|
# torture_bootargs="[ kernel boot arguments ]"
|
|
# torture_set flavor [ kvm.sh arguments ]
|
|
#
|
|
# Note that "flavor" is an arbitrary string that does not affect kvm.sh
|
|
# in any way. So also supply --torture if you need something other than
|
|
# the default.
|
|
function torture_set {
|
|
local cur_kcsan_kmake_args=
|
|
local kcsan_kmake_tag=
|
|
local flavor=$1
|
|
shift
|
|
curflavor=$flavor
|
|
torture_one "$@"
|
|
mv $T/last-resdir $T/last-resdir-nodebug || :
|
|
if test "$do_kasan" = "yes"
|
|
then
|
|
curflavor=${flavor}-kasan
|
|
torture_one "$@" --kasan
|
|
mv $T/last-resdir $T/last-resdir-kasan || :
|
|
fi
|
|
if test "$do_kcsan" = "yes"
|
|
then
|
|
curflavor=${flavor}-kcsan
|
|
if test -n "$kcsan_kmake_args"
|
|
then
|
|
kcsan_kmake_tag="--kmake-args"
|
|
cur_kcsan_kmake_args="$kcsan_kmake_args"
|
|
fi
|
|
torture_one "$@" --kconfig "CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=y" $kcsan_kmake_tag $cur_kcsan_kmake_args --kcsan
|
|
mv $T/last-resdir $T/last-resdir-kcsan || :
|
|
fi
|
|
}
|
|
|
|
# make allmodconfig
|
|
if test "$do_allmodconfig" = "yes"
|
|
then
|
|
echo " --- allmodconfig:" Start `date` | tee -a $T/log
|
|
amcdir="tools/testing/selftests/rcutorture/res/$ds/allmodconfig"
|
|
mkdir -p "$amcdir"
|
|
echo " --- make clean" | tee $amcdir/log > "$amcdir/Make.out" 2>&1
|
|
make -j$MAKE_ALLOTED_CPUS clean >> "$amcdir/Make.out" 2>&1
|
|
retcode=$?
|
|
buildphase='"make clean"'
|
|
if test "$retcode" -eq 0
|
|
then
|
|
echo " --- make allmodconfig" | tee -a $amcdir/log >> "$amcdir/Make.out" 2>&1
|
|
cp .config $amcdir
|
|
make -j$MAKE_ALLOTED_CPUS allmodconfig >> "$amcdir/Make.out" 2>&1
|
|
retcode=$?
|
|
buildphase='"make allmodconfig"'
|
|
fi
|
|
if test "$retcode" -eq 0
|
|
then
|
|
echo " --- make " | tee -a $amcdir/log >> "$amcdir/Make.out" 2>&1
|
|
make -j$MAKE_ALLOTED_CPUS >> "$amcdir/Make.out" 2>&1
|
|
retcode="$?"
|
|
echo $retcode > "$amcdir/Make.exitcode"
|
|
buildphase='"make"'
|
|
fi
|
|
if test "$retcode" -eq 0
|
|
then
|
|
echo "allmodconfig($retcode)" $amcdir >> $T/successes
|
|
echo Success >> $amcdir/log
|
|
else
|
|
echo "allmodconfig($retcode)" $amcdir >> $T/failures
|
|
echo " --- allmodconfig Test summary:" >> $amcdir/log
|
|
echo " --- Summary: Exit code $retcode from $buildphase, see Make.out" >> $amcdir/log
|
|
fi
|
|
fi
|
|
|
|
# Test building RCU Tasks flavors in isolation, both SMP and !SMP
|
|
if test "$do_rcutasksflavors" = "yes"
|
|
then
|
|
echo " --- rcutasksflavors:" Start `date` | tee -a $T/log
|
|
rtfdir="tools/testing/selftests/rcutorture/res/$ds/results-rcutasksflavors"
|
|
mkdir -p "$rtfdir"
|
|
cat > $T/rcutasksflavors << __EOF__
|
|
#CHECK#CONFIG_TASKS_RCU=n
|
|
#CHECK#CONFIG_TASKS_RUDE_RCU=n
|
|
#CHECK#CONFIG_TASKS_TRACE_RCU=n
|
|
__EOF__
|
|
for flavor in CONFIG_TASKS_RCU CONFIG_TASKS_RUDE_RCU CONFIG_TASKS_TRACE_RCU
|
|
do
|
|
forceflavor="`echo $flavor | sed -e 's/^CONFIG/CONFIG_FORCE/'`"
|
|
deselectedflavors="`grep -v $flavor $T/rcutasksflavors | tr '\012' ' ' | tr -s ' ' | sed -e 's/ *$//'`"
|
|
echo " --- Running RCU Tasks Trace flavor $flavor `date`" >> $rtfdir/log
|
|
tools/testing/selftests/rcutorture/bin/kvm.sh --datestamp "$ds/results-rcutasksflavors/$flavor" --buildonly --configs "TINY01 TREE04" --kconfig "CONFIG_RCU_EXPERT=y CONFIG_RCU_SCALE_TEST=y $forceflavor=y $deselectedflavors" --trust-make > $T/$flavor.out 2>&1
|
|
retcode=$?
|
|
if test "$retcode" -ne 0
|
|
then
|
|
break
|
|
fi
|
|
done
|
|
if test "$retcode" -eq 0
|
|
then
|
|
echo "rcutasksflavors($retcode)" $rtfdir >> $T/successes
|
|
echo Success >> $rtfdir/log
|
|
else
|
|
echo "rcutasksflavors($retcode)" $rtfdir >> $T/failures
|
|
echo " --- rcutasksflavors Test summary:" >> $rtfdir/log
|
|
echo " --- Summary: Exit code $retcode from $flavor, see Make.out" >> $rtfdir/log
|
|
fi
|
|
fi
|
|
|
|
# --torture rcu
|
|
if test "$do_rcutorture" = "yes"
|
|
then
|
|
torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000"
|
|
torture_set "rcutorture" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "$configs_rcutorture" --trust-make
|
|
fi
|
|
|
|
if test "$do_locktorture" = "yes"
|
|
then
|
|
torture_bootargs="torture.disable_onoff_at_boot"
|
|
torture_set "locktorture" tools/testing/selftests/rcutorture/bin/kvm.sh --torture lock --allcpus --duration "$duration_locktorture" --configs "$configs_locktorture" --trust-make
|
|
fi
|
|
|
|
if test "$do_scftorture" = "yes"
|
|
then
|
|
# Scale memory based on the number of CPUs.
|
|
scfmem=$((2+HALF_ALLOTED_CPUS/16))
|
|
torture_bootargs="scftorture.nthreads=$HALF_ALLOTED_CPUS torture.disable_onoff_at_boot csdlock_debug=1"
|
|
torture_set "scftorture" tools/testing/selftests/rcutorture/bin/kvm.sh --torture scf --allcpus --duration "$duration_scftorture" --configs "$configs_scftorture" --kconfig "CONFIG_NR_CPUS=$HALF_ALLOTED_CPUS" --memory ${scfmem}G --trust-make
|
|
fi
|
|
|
|
if test "$do_rt" = "yes"
|
|
then
|
|
# With all post-boot grace periods forced to normal.
|
|
torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 rcupdate.rcu_normal=1"
|
|
torture_set "rcurttorture" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "TREE03" --trust-make
|
|
|
|
# With all post-boot grace periods forced to expedited.
|
|
torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 rcupdate.rcu_expedited=1"
|
|
torture_set "rcurttorture-exp" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "TREE03" --trust-make
|
|
fi
|
|
|
|
if test "$do_srcu_lockdep" = "yes"
|
|
then
|
|
echo " --- do-srcu-lockdep:" Start `date` | tee -a $T/log
|
|
tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh --datestamp "$ds/results-srcu-lockdep" > $T/srcu_lockdep.sh.out 2>&1
|
|
retcode=$?
|
|
cp $T/srcu_lockdep.sh.out "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep/log"
|
|
if test "$retcode" -eq 0
|
|
then
|
|
echo "srcu_lockdep($retcode)" "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep" >> $T/successes
|
|
echo Success >> "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep/log"
|
|
else
|
|
echo "srcu_lockdep($retcode)" "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep" >> $T/failures
|
|
echo " --- srcu_lockdep Test Summary:" >> "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep/log"
|
|
echo " --- Summary: Exit code $retcode from srcu_lockdep.sh, see ds/results-srcu-lockdep" >> "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep/log"
|
|
fi
|
|
fi
|
|
|
|
if test "$do_refscale" = yes
|
|
then
|
|
primlist="`grep '\.name[ ]*=' kernel/rcu/refscale.c | sed -e 's/^[^"]*"//' -e 's/".*$//'`"
|
|
else
|
|
primlist=
|
|
fi
|
|
firsttime=1
|
|
do_kasan_save="$do_kasan"
|
|
do_kcsan_save="$do_kcsan"
|
|
for prim in $primlist
|
|
do
|
|
if test -n "$firsttime"
|
|
then
|
|
torture_bootargs="refscale.scale_type="$prim" refscale.nreaders=$HALF_ALLOTED_CPUS refscale.loops=10000 refscale.holdoff=20 torture.disable_onoff_at_boot"
|
|
torture_set "refscale-$prim" tools/testing/selftests/rcutorture/bin/kvm.sh --torture refscale --allcpus --duration 5 --kconfig "CONFIG_TASKS_TRACE_RCU=y CONFIG_NR_CPUS=$HALF_ALLOTED_CPUS" --bootargs "refscale.verbose_batched=$VERBOSE_BATCH_CPUS torture.verbose_sleep_frequency=8 torture.verbose_sleep_duration=$VERBOSE_BATCH_CPUS" --trust-make
|
|
mv $T/last-resdir-nodebug $T/first-resdir-nodebug || :
|
|
if test -f "$T/last-resdir-kasan"
|
|
then
|
|
mv $T/last-resdir-kasan $T/first-resdir-kasan || :
|
|
fi
|
|
if test -f "$T/last-resdir-kcsan"
|
|
then
|
|
mv $T/last-resdir-kcsan $T/first-resdir-kcsan || :
|
|
fi
|
|
firsttime=
|
|
do_kasan=
|
|
do_kcsan=
|
|
else
|
|
torture_bootargs=
|
|
for i in $T/first-resdir-*
|
|
do
|
|
case "$i" in
|
|
*-nodebug)
|
|
torture_suffix=
|
|
;;
|
|
*-kasan)
|
|
torture_suffix="-kasan"
|
|
;;
|
|
*-kcsan)
|
|
torture_suffix="-kcsan"
|
|
;;
|
|
esac
|
|
torture_set "refscale-$prim$torture_suffix" tools/testing/selftests/rcutorture/bin/kvm-again.sh "`cat "$i"`" --duration 5 --bootargs "refscale.scale_type=$prim"
|
|
done
|
|
fi
|
|
done
|
|
do_kasan="$do_kasan_save"
|
|
do_kcsan="$do_kcsan_save"
|
|
|
|
if test "$do_rcuscale" = yes
|
|
then
|
|
primlist="`grep '\.name[ ]*=' kernel/rcu/rcuscale.c | sed -e 's/^[^"]*"//' -e 's/".*$//'`"
|
|
else
|
|
primlist=
|
|
fi
|
|
firsttime=1
|
|
do_kasan_save="$do_kasan"
|
|
do_kcsan_save="$do_kcsan"
|
|
for prim in $primlist
|
|
do
|
|
if test -n "$firsttime"
|
|
then
|
|
torture_bootargs="rcuscale.scale_type="$prim" rcuscale.nwriters=$HALF_ALLOTED_CPUS rcuscale.holdoff=20 torture.disable_onoff_at_boot"
|
|
torture_set "rcuscale-$prim" tools/testing/selftests/rcutorture/bin/kvm.sh --torture rcuscale --allcpus --duration 5 --kconfig "CONFIG_TASKS_TRACE_RCU=y CONFIG_NR_CPUS=$HALF_ALLOTED_CPUS" --trust-make
|
|
mv $T/last-resdir-nodebug $T/first-resdir-nodebug || :
|
|
if test -f "$T/last-resdir-kasan"
|
|
then
|
|
mv $T/last-resdir-kasan $T/first-resdir-kasan || :
|
|
fi
|
|
if test -f "$T/last-resdir-kcsan"
|
|
then
|
|
mv $T/last-resdir-kcsan $T/first-resdir-kcsan || :
|
|
fi
|
|
firsttime=
|
|
do_kasan=
|
|
do_kcsan=
|
|
else
|
|
torture_bootargs=
|
|
for i in $T/first-resdir-*
|
|
do
|
|
case "$i" in
|
|
*-nodebug)
|
|
torture_suffix=
|
|
;;
|
|
*-kasan)
|
|
torture_suffix="-kasan"
|
|
;;
|
|
*-kcsan)
|
|
torture_suffix="-kcsan"
|
|
;;
|
|
esac
|
|
torture_set "rcuscale-$prim$torture_suffix" tools/testing/selftests/rcutorture/bin/kvm-again.sh "`cat "$i"`" --duration 5 --bootargs "rcuscale.scale_type=$prim"
|
|
done
|
|
fi
|
|
done
|
|
do_kasan="$do_kasan_save"
|
|
do_kcsan="$do_kcsan_save"
|
|
|
|
if test "$do_kvfree" = "yes"
|
|
then
|
|
torture_bootargs="rcuscale.kfree_rcu_test=1 rcuscale.kfree_nthreads=16 rcuscale.holdoff=20 rcuscale.kfree_loops=10000 torture.disable_onoff_at_boot"
|
|
torture_set "rcuscale-kvfree" tools/testing/selftests/rcutorture/bin/kvm.sh --torture rcuscale --allcpus --duration 10 --kconfig "CONFIG_NR_CPUS=$HALF_ALLOTED_CPUS" --memory 2G --trust-make
|
|
fi
|
|
|
|
if test "$do_clocksourcewd" = "yes"
|
|
then
|
|
torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog"
|
|
torture_set "clocksourcewd-1" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make
|
|
|
|
torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog"
|
|
torture_set "clocksourcewd-2" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make
|
|
|
|
# In case our work is already done...
|
|
if test "$do_rcutorture" != "yes"
|
|
then
|
|
torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog"
|
|
torture_set "clocksourcewd-3" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --trust-make
|
|
fi
|
|
fi
|
|
|
|
echo " --- " $scriptname $args
|
|
echo " --- " Done `date` | tee -a $T/log
|
|
ret=0
|
|
nsuccesses=0
|
|
echo SUCCESSES: | tee -a $T/log
|
|
if test -s "$T/successes"
|
|
then
|
|
cat "$T/successes" | tee -a $T/log
|
|
nsuccesses="`wc -l "$T/successes" | awk '{ print $1 }'`"
|
|
fi
|
|
nfailures=0
|
|
echo FAILURES: | tee -a $T/log
|
|
if test -s "$T/failures"
|
|
then
|
|
awk < "$T/failures" -v sq="'" '{ print "echo " sq $0 sq; print "sed -e " sq "1,/^ --- .* Test summary:$/d" sq " " $2 "/log | grep Summary: | sed -e " sq "s/^[^S]*/ /" sq; }' | sh | tee -a $T/log | tee "$T/failuresum"
|
|
nfailures="`wc -l "$T/failures" | awk '{ print $1 }'`"
|
|
grep "^ Summary: " "$T/failuresum" |
|
|
grep -v '^ Summary: Bugs: [0-9]* (all bugs kcsan)$' > "$T/nonkcsan"
|
|
if test -s "$T/nonkcsan"
|
|
then
|
|
nonkcsanbug="yes"
|
|
fi
|
|
ret=2
|
|
fi
|
|
if test "$do_kcsan" = "yes"
|
|
then
|
|
TORTURE_KCONFIG_KCSAN_ARG=1 tools/testing/selftests/rcutorture/bin/kcsan-collapse.sh tools/testing/selftests/rcutorture/res/$ds > tools/testing/selftests/rcutorture/res/$ds/kcsan.sum
|
|
fi
|
|
echo Started at $startdate, ended at `date`, duration `get_starttime_duration $starttime`. | tee -a $T/log
|
|
echo Summary: Successes: $nsuccesses Failures: $nfailures. | tee -a $T/log
|
|
tdir="`cat $T/successes $T/failures | head -1 | awk '{ print $NF }' | sed -e 's,/[^/]\+/*$,,'`"
|
|
find "$tdir" -name 'ConfigFragment.diags' -print > $T/configerrors
|
|
find "$tdir" -name 'Make.out.diags' -print > $T/builderrors
|
|
if test -s "$T/configerrors"
|
|
then
|
|
echo " Scenarios with .config errors: `wc -l "$T/configerrors" | awk '{ print $1 }'`"
|
|
nonkcsanbug="yes"
|
|
fi
|
|
if test -s "$T/builderrors"
|
|
then
|
|
echo " Scenarios with build errors: `wc -l "$T/builderrors" | awk '{ print $1 }'`"
|
|
nonkcsanbug="yes"
|
|
fi
|
|
if test -z "$nonkcsanbug" && test -s "$T/failuresum"
|
|
then
|
|
echo " All bugs were KCSAN failures."
|
|
fi
|
|
if test -n "$tdir" && test $compress_concurrency -gt 0
|
|
then
|
|
# KASAN vmlinux files can approach 1GB in size, so compress them.
|
|
echo Looking for K[AC]SAN files to compress: `date` > "$tdir/log-xz" 2>&1
|
|
find "$tdir" -type d -name '*-k[ac]san' -print > $T/xz-todo-all
|
|
find "$tdir" -type f -name 're-run' -print | sed -e 's,/re-run,,' |
|
|
grep -e '-k[ac]san$' > $T/xz-todo-copy
|
|
sort $T/xz-todo-all $T/xz-todo-copy | uniq -u > $T/xz-todo
|
|
ncompresses=0
|
|
batchno=1
|
|
if test -s $T/xz-todo
|
|
then
|
|
for i in `cat $T/xz-todo`
|
|
do
|
|
find $i -name 'vmlinux*' -print
|
|
done | wc -l | awk '{ print $1 }' > $T/xz-todo-count
|
|
n2compress="`cat $T/xz-todo-count`"
|
|
echo Size before compressing $n2compress files: `du -sh $tdir | awk '{ print $1 }'` `date` 2>&1 | tee -a "$tdir/log-xz" | tee -a $T/log
|
|
for i in `cat $T/xz-todo`
|
|
do
|
|
echo Compressing vmlinux files in ${i}: `date` >> "$tdir/log-xz" 2>&1
|
|
for j in $i/*/vmlinux
|
|
do
|
|
xz "$j" >> "$tdir/log-xz" 2>&1 &
|
|
ncompresses=$((ncompresses+1))
|
|
if test $ncompresses -ge $compress_concurrency
|
|
then
|
|
echo Waiting for batch $batchno of $ncompresses compressions `date` | tee -a "$tdir/log-xz" | tee -a $T/log
|
|
wait
|
|
ncompresses=0
|
|
batchno=$((batchno+1))
|
|
fi
|
|
done
|
|
done
|
|
if test $ncompresses -gt 0
|
|
then
|
|
echo Waiting for final batch $batchno of $ncompresses compressions `date` | tee -a "$tdir/log-xz" | tee -a $T/log
|
|
fi
|
|
wait
|
|
if test -s $T/xz-todo-copy
|
|
then
|
|
# The trick here is that we need corresponding
|
|
# vmlinux files from corresponding scenarios.
|
|
echo Linking vmlinux.xz files to re-use scenarios `date` | tee -a "$tdir/log-xz" | tee -a $T/log
|
|
dirstash="`pwd`"
|
|
for i in `cat $T/xz-todo-copy`
|
|
do
|
|
cd $i
|
|
find . -name vmlinux -print > $T/xz-todo-copy-vmlinux
|
|
for v in `cat $T/xz-todo-copy-vmlinux`
|
|
do
|
|
rm -f "$v"
|
|
cp -l `cat $i/re-run`/"$i/$v".xz "`dirname "$v"`"
|
|
done
|
|
cd "$dirstash"
|
|
done
|
|
fi
|
|
echo Size after compressing $n2compress files: `du -sh $tdir | awk '{ print $1 }'` `date` 2>&1 | tee -a "$tdir/log-xz" | tee -a $T/log
|
|
echo Total duration `get_starttime_duration $starttime`. | tee -a $T/log
|
|
else
|
|
echo No compression needed: `date` >> "$tdir/log-xz" 2>&1
|
|
fi
|
|
fi
|
|
if test -n "$tdir"
|
|
then
|
|
cp $T/log "$tdir"
|
|
fi
|
|
exit $ret
|