xref: /linux/tools/testing/selftests/rcutorture/bin/torture.sh (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0+
3#
4# Run a series of torture tests, intended for overnight or
5# longer timeframes, and also for large systems.
6#
7# Usage: torture.sh [ options ]
8#
9# Copyright (C) 2020 Facebook, Inc.
10#
11# Authors: Paul E. McKenney <paulmck@kernel.org>
12
13scriptname=$0
14args="$*"
15
16RCUTORTURE="`pwd`/tools/testing/selftests/rcutorture"; export RCUTORTURE
17PATH=${RCUTORTURE}/bin:$PATH; export PATH
18. functions.sh
19
20TORTURE_ALLOTED_CPUS="`identify_qemu_vcpus`"
21MAKE_ALLOTED_CPUS=$((TORTURE_ALLOTED_CPUS*2))
22SCALE_ALLOTED_CPUS=$((TORTURE_ALLOTED_CPUS/2))
23if test "$SCALE_ALLOTED_CPUS" -lt 1
24then
25	SCALE_ALLOTED_CPUS=1
26fi
27VERBOSE_BATCH_CPUS=$((TORTURE_ALLOTED_CPUS/16))
28if test "$VERBOSE_BATCH_CPUS" -lt 2
29then
30	VERBOSE_BATCH_CPUS=0
31fi
32
33# Configurations/scenarios.
34configs_rcutorture=
35configs_locktorture=
36configs_scftorture=
37kcsan_kmake_args=
38
39# Default compression, duration, and apportionment.
40compress_concurrency="`identify_qemu_vcpus`"
41duration_base=10
42duration_rcutorture_frac=7
43duration_locktorture_frac=1
44duration_scftorture_frac=2
45
46# "yes" or "no" parameters
47do_allmodconfig=yes
48do_rcutorture=yes
49do_locktorture=yes
50do_scftorture=yes
51do_rcuscale=yes
52do_refscale=yes
53do_kvfree=yes
54do_kasan=yes
55do_kcsan=no
56do_clocksourcewd=yes
57do_rt=yes
58do_rcutasksflavors=yes
59do_srcu_lockdep=yes
60
61# doyesno - Helper function for yes/no arguments
62function doyesno () {
63	if test "$1" = "$2"
64	then
65		echo yes
66	else
67		echo no
68	fi
69}
70
71usage () {
72	echo "Usage: $scriptname optional arguments:"
73	echo "       --compress-concurrency concurrency"
74	echo "       --configs-rcutorture \"config-file list w/ repeat factor (3*TINY01)\""
75	echo "       --configs-locktorture \"config-file list w/ repeat factor (10*LOCK01)\""
76	echo "       --configs-scftorture \"config-file list w/ repeat factor (2*CFLIST)\""
77	echo "       --do-all"
78	echo "       --do-allmodconfig / --do-no-allmodconfig / --no-allmodconfig"
79	echo "       --do-clocksourcewd / --do-no-clocksourcewd / --no-clocksourcewd"
80	echo "       --do-kasan / --do-no-kasan / --no-kasan"
81	echo "       --do-kcsan / --do-no-kcsan / --no-kcsan"
82	echo "       --do-kvfree / --do-no-kvfree / --no-kvfree"
83	echo "       --do-locktorture / --do-no-locktorture / --no-locktorture"
84	echo "       --do-none"
85	echo "       --do-rcuscale / --do-no-rcuscale / --no-rcuscale"
86	echo "       --do-rcutasksflavors / --do-no-rcutasksflavors / --no-rcutasksflavors"
87	echo "       --do-rcutorture / --do-no-rcutorture / --no-rcutorture"
88	echo "       --do-refscale / --do-no-refscale / --no-refscale"
89	echo "       --do-rt / --do-no-rt / --no-rt"
90	echo "       --do-scftorture / --do-no-scftorture / --no-scftorture"
91	echo "       --do-srcu-lockdep / --do-no-srcu-lockdep / --no-srcu-lockdep"
92	echo "       --duration [ <minutes> | <hours>h | <days>d ]"
93	echo "       --guest-cpu-limit N"
94	echo "       --kcsan-kmake-arg kernel-make-arguments"
95	exit 1
96}
97
98while test $# -gt 0
99do
100	case "$1" in
101	--compress-concurrency)
102		checkarg --compress-concurrency "(concurrency level)" $# "$2" '^[0-9][0-9]*$' '^error'
103		compress_concurrency=$2
104		shift
105		;;
106	--config-rcutorture|--configs-rcutorture)
107		checkarg --configs-rcutorture "(list of config files)" "$#" "$2" '^[^/]\+$' '^--'
108		configs_rcutorture="$configs_rcutorture $2"
109		shift
110		;;
111	--config-locktorture|--configs-locktorture)
112		checkarg --configs-locktorture "(list of config files)" "$#" "$2" '^[^/]\+$' '^--'
113		configs_locktorture="$configs_locktorture $2"
114		shift
115		;;
116	--config-scftorture|--configs-scftorture)
117		checkarg --configs-scftorture "(list of config files)" "$#" "$2" '^[^/]\+$' '^--'
118		configs_scftorture="$configs_scftorture $2"
119		shift
120		;;
121	--do-all|--doall)
122		do_allmodconfig=yes
123		do_rcutasksflavor=yes
124		do_rcutorture=yes
125		do_locktorture=yes
126		do_scftorture=yes
127		do_rcuscale=yes
128		do_refscale=yes
129		do_rt=yes
130		do_kvfree=yes
131		do_kasan=yes
132		do_kcsan=yes
133		do_clocksourcewd=yes
134		do_srcu_lockdep=yes
135		;;
136	--do-allmodconfig|--do-no-allmodconfig|--no-allmodconfig)
137		do_allmodconfig=`doyesno "$1" --do-allmodconfig`
138		;;
139	--do-clocksourcewd|--do-no-clocksourcewd|--no-clocksourcewd)
140		do_clocksourcewd=`doyesno "$1" --do-clocksourcewd`
141		;;
142	--do-kasan|--do-no-kasan|--no-kasan)
143		do_kasan=`doyesno "$1" --do-kasan`
144		;;
145	--do-kcsan|--do-no-kcsan|--no-kcsan)
146		do_kcsan=`doyesno "$1" --do-kcsan`
147		;;
148	--do-kvfree|--do-no-kvfree|--no-kvfree)
149		do_kvfree=`doyesno "$1" --do-kvfree`
150		;;
151	--do-locktorture|--do-no-locktorture|--no-locktorture)
152		do_locktorture=`doyesno "$1" --do-locktorture`
153		;;
154	--do-none|--donone)
155		do_allmodconfig=no
156		do_rcutasksflavors=no
157		do_rcutorture=no
158		do_locktorture=no
159		do_scftorture=no
160		do_rcuscale=no
161		do_refscale=no
162		do_rt=no
163		do_kvfree=no
164		do_kasan=no
165		do_kcsan=no
166		do_clocksourcewd=no
167		do_srcu_lockdep=no
168		;;
169	--do-rcuscale|--do-no-rcuscale|--no-rcuscale)
170		do_rcuscale=`doyesno "$1" --do-rcuscale`
171		;;
172	--do-rcutasksflavors|--do-no-rcutasksflavors|--no-rcutasksflavors)
173		do_rcutasksflavors=`doyesno "$1" --do-rcutasksflavors`
174		;;
175	--do-rcutorture|--do-no-rcutorture|--no-rcutorture)
176		do_rcutorture=`doyesno "$1" --do-rcutorture`
177		;;
178	--do-refscale|--do-no-refscale|--no-refscale)
179		do_refscale=`doyesno "$1" --do-refscale`
180		;;
181	--do-rt|--do-no-rt|--no-rt)
182		do_rt=`doyesno "$1" --do-rt`
183		;;
184	--do-scftorture|--do-no-scftorture|--no-scftorture)
185		do_scftorture=`doyesno "$1" --do-scftorture`
186		;;
187	--do-srcu-lockdep|--do-no-srcu-lockdep|--no-srcu-lockdep)
188		do_srcu_lockdep=`doyesno "$1" --do-srcu-lockdep`
189		;;
190	--duration)
191		checkarg --duration "(minutes)" $# "$2" '^[0-9][0-9]*\(m\|h\|d\|\)$' '^error'
192		mult=1
193		if echo "$2" | grep -q 'm$'
194		then
195			mult=1
196		elif echo "$2" | grep -q 'h$'
197		then
198			mult=60
199		elif echo "$2" | grep -q 'd$'
200		then
201			mult=1440
202		fi
203		ts=`echo $2 | sed -e 's/[smhd]$//'`
204		duration_base=$(($ts*mult))
205		shift
206		;;
207	--guest-cpu-limit|--guest-cpu-lim)
208		checkarg --guest-cpu-limit "(number)" "$#" "$2" '^[0-9]*$' '^--'
209		if (("$2" <= "$TORTURE_ALLOTED_CPUS" / 2))
210		then
211			SCALE_ALLOTED_CPUS="$2"
212			VERBOSE_BATCH_CPUS="$((SCALE_ALLOTED_CPUS/8))"
213			if (("$VERBOSE_BATCH_CPUS" < 2))
214			then
215				VERBOSE_BATCH_CPUS=0
216			fi
217		else
218			echo "Ignoring value of $2 for --guest-cpu-limit which is greater than (("$TORTURE_ALLOTED_CPUS" / 2))."
219		fi
220		shift
221		;;
222	--kcsan-kmake-arg|--kcsan-kmake-args)
223		checkarg --kcsan-kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$'
224		kcsan_kmake_args="`echo "$kcsan_kmake_args $2" | sed -e 's/^ *//' -e 's/ *$//'`"
225		shift
226		;;
227	*)
228		echo Unknown argument $1
229		usage
230		;;
231	esac
232	shift
233done
234
235ds="`date +%Y.%m.%d-%H.%M.%S`-torture"
236startdate="`date`"
237starttime="`get_starttime`"
238
239T="`mktemp -d ${TMPDIR-/tmp}/torture.sh.XXXXXX`"
240trap 'rm -rf $T' 0 2
241
242echo " --- " $scriptname $args | tee -a $T/log
243echo " --- Results directory: " $ds | tee -a $T/log
244
245# Calculate rcutorture defaults and apportion time
246if test -z "$configs_rcutorture"
247then
248	configs_rcutorture=CFLIST
249fi
250duration_rcutorture=$((duration_base*duration_rcutorture_frac/10))
251if test "$duration_rcutorture" -eq 0
252then
253	echo " --- Zero time for rcutorture, disabling" | tee -a $T/log
254	do_rcutorture=no
255fi
256
257# Calculate locktorture defaults and apportion time
258if test -z "$configs_locktorture"
259then
260	configs_locktorture=CFLIST
261fi
262duration_locktorture=$((duration_base*duration_locktorture_frac/10))
263if test "$duration_locktorture" -eq 0
264then
265	echo " --- Zero time for locktorture, disabling" | tee -a $T/log
266	do_locktorture=no
267fi
268
269# Calculate scftorture defaults and apportion time
270if test -z "$configs_scftorture"
271then
272	configs_scftorture=CFLIST
273fi
274duration_scftorture=$((duration_base*duration_scftorture_frac/10))
275if test "$duration_scftorture" -eq 0
276then
277	echo " --- Zero time for scftorture, disabling" | tee -a $T/log
278	do_scftorture=no
279fi
280
281touch $T/failures
282touch $T/successes
283
284# torture_one - Does a single kvm.sh run.
285#
286# Usage:
287#	torture_bootargs="[ kernel boot arguments ]"
288#	torture_one flavor [ kvm.sh arguments ]
289#
290# Note that "flavor" is an arbitrary string.  Supply --torture if needed.
291# Note that quoting is problematic.  So on the command line, pass multiple
292# values with multiple kvm.sh argument instances.
293function torture_one {
294	local cur_bootargs=
295	local boottag=
296
297	echo " --- $curflavor:" Start `date` | tee -a $T/log
298	if test -n "$torture_bootargs"
299	then
300		boottag="--bootargs"
301		cur_bootargs="$torture_bootargs"
302	fi
303	"$@" $boottag "$cur_bootargs" --datestamp "$ds/results-$curflavor" > $T/$curflavor.out 2>&1
304	retcode=$?
305	resdir="`grep '^Results directory: ' $T/$curflavor.out | tail -1 | sed -e 's/^Results directory: //'`"
306	if test -z "$resdir"
307	then
308		cat $T/$curflavor.out | tee -a $T/log
309		echo retcode=$retcode | tee -a $T/log
310	else
311		echo $resdir > $T/last-resdir
312	fi
313	if test "$retcode" == 0
314	then
315		echo "$curflavor($retcode)" $resdir >> $T/successes
316	else
317		echo "$curflavor($retcode)" $resdir >> $T/failures
318	fi
319}
320
321# torture_set - Does a set of tortures with and without KASAN and KCSAN.
322#
323# Usage:
324#	torture_bootargs="[ kernel boot arguments ]"
325#	torture_set flavor [ kvm.sh arguments ]
326#
327# Note that "flavor" is an arbitrary string that does not affect kvm.sh
328# in any way.  So also supply --torture if you need something other than
329# the default.
330function torture_set {
331	local cur_kcsan_kmake_args=
332	local kcsan_kmake_tag=
333	local flavor=$1
334	shift
335	curflavor=$flavor
336	torture_one "$@"
337	mv $T/last-resdir $T/last-resdir-nodebug || :
338	if test "$do_kasan" = "yes"
339	then
340		curflavor=${flavor}-kasan
341		torture_one "$@" --kasan
342		mv $T/last-resdir $T/last-resdir-kasan || :
343	fi
344	if test "$do_kcsan" = "yes"
345	then
346		curflavor=${flavor}-kcsan
347		if test -n "$kcsan_kmake_args"
348		then
349			kcsan_kmake_tag="--kmake-args"
350			cur_kcsan_kmake_args="$kcsan_kmake_args"
351		fi
352		torture_one "$@" --kconfig "CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=y" $kcsan_kmake_tag $cur_kcsan_kmake_args --kcsan
353		mv $T/last-resdir $T/last-resdir-kcsan || :
354	fi
355}
356
357# make allmodconfig
358if test "$do_allmodconfig" = "yes"
359then
360	echo " --- allmodconfig:" Start `date` | tee -a $T/log
361	amcdir="tools/testing/selftests/rcutorture/res/$ds/allmodconfig"
362	mkdir -p "$amcdir"
363	echo " --- make clean" | tee $amcdir/log > "$amcdir/Make.out" 2>&1
364	make -j$MAKE_ALLOTED_CPUS clean >> "$amcdir/Make.out" 2>&1
365	retcode=$?
366	buildphase='"make clean"'
367	if test "$retcode" -eq 0
368	then
369		echo " --- make allmodconfig" | tee -a $amcdir/log >> "$amcdir/Make.out" 2>&1
370		cp .config $amcdir
371		make -j$MAKE_ALLOTED_CPUS allmodconfig >> "$amcdir/Make.out" 2>&1
372		retcode=$?
373		buildphase='"make allmodconfig"'
374	fi
375	if test "$retcode" -eq 0
376	then
377		echo " --- make " | tee -a $amcdir/log >> "$amcdir/Make.out" 2>&1
378		make -j$MAKE_ALLOTED_CPUS >> "$amcdir/Make.out" 2>&1
379		retcode="$?"
380		echo $retcode > "$amcdir/Make.exitcode"
381		buildphase='"make"'
382	fi
383	if test "$retcode" -eq 0
384	then
385		echo "allmodconfig($retcode)" $amcdir >> $T/successes
386		echo Success >> $amcdir/log
387	else
388		echo "allmodconfig($retcode)" $amcdir >> $T/failures
389		echo " --- allmodconfig Test summary:" >> $amcdir/log
390		echo " --- Summary: Exit code $retcode from $buildphase, see Make.out" >> $amcdir/log
391	fi
392fi
393
394# Test building RCU Tasks flavors in isolation, both SMP and !SMP
395if test "$do_rcutasksflavors" = "yes"
396then
397	echo " --- rcutasksflavors:" Start `date` | tee -a $T/log
398	rtfdir="tools/testing/selftests/rcutorture/res/$ds/results-rcutasksflavors"
399	mkdir -p "$rtfdir"
400	cat > $T/rcutasksflavors << __EOF__
401#CHECK#CONFIG_TASKS_RCU=n
402#CHECK#CONFIG_TASKS_RUDE_RCU=n
403#CHECK#CONFIG_TASKS_TRACE_RCU=n
404__EOF__
405	for flavor in CONFIG_TASKS_RCU CONFIG_TASKS_RUDE_RCU CONFIG_TASKS_TRACE_RCU
406	do
407		forceflavor="`echo $flavor | sed -e 's/^CONFIG/CONFIG_FORCE/'`"
408		deselectedflavors="`grep -v $flavor $T/rcutasksflavors | tr '\012' ' ' | tr -s ' ' | sed -e 's/ *$//'`"
409		echo " --- Running RCU Tasks Trace flavor $flavor `date`" >> $rtfdir/log
410		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 CONFIG_KPROBES=n CONFIG_RCU_TRACE=n CONFIG_TRACING=n CONFIG_BLK_DEV_IO_TRACE=n CONFIG_UPROBE_EVENTS=n $forceflavor=y $deselectedflavors" --trust-make > $T/$flavor.out 2>&1
411		retcode=$?
412		if test "$retcode" -ne 0
413		then
414			break
415		fi
416	done
417	if test "$retcode" -eq 0
418	then
419		echo "rcutasksflavors($retcode)" $rtfdir >> $T/successes
420		echo Success >> $rtfdir/log
421	else
422		echo "rcutasksflavors($retcode)" $rtfdir >> $T/failures
423		echo " --- rcutasksflavors Test summary:" >> $rtfdir/log
424		echo " --- Summary: Exit code $retcode from $flavor, see Make.out" >> $rtfdir/log
425	fi
426fi
427
428# --torture rcu
429if test "$do_rcutorture" = "yes"
430then
431	torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000"
432	torture_set "rcutorture" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "$configs_rcutorture" --trust-make
433fi
434
435if test "$do_locktorture" = "yes"
436then
437	torture_bootargs="torture.disable_onoff_at_boot"
438	torture_set "locktorture" tools/testing/selftests/rcutorture/bin/kvm.sh --torture lock --allcpus --duration "$duration_locktorture" --configs "$configs_locktorture" --trust-make
439fi
440
441if test "$do_scftorture" = "yes"
442then
443	# Scale memory based on the number of CPUs.
444	scfmem=$((3+SCALE_ALLOTED_CPUS/16))
445	torture_bootargs="scftorture.nthreads=$SCALE_ALLOTED_CPUS torture.disable_onoff_at_boot csdlock_debug=1"
446	torture_set "scftorture" tools/testing/selftests/rcutorture/bin/kvm.sh --torture scf --allcpus --duration "$duration_scftorture" --configs "$configs_scftorture" --kconfig "CONFIG_NR_CPUS=$SCALE_ALLOTED_CPUS" --memory ${scfmem}G --trust-make
447fi
448
449if test "$do_rt" = "yes"
450then
451	# With all post-boot grace periods forced to normal.
452	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"
453	torture_set "rcurttorture" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "TREE03" --trust-make
454
455	# With all post-boot grace periods forced to expedited.
456	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"
457	torture_set "rcurttorture-exp" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "TREE03" --trust-make
458fi
459
460if test "$do_srcu_lockdep" = "yes"
461then
462	echo " --- do-srcu-lockdep:" Start `date` | tee -a $T/log
463	tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh --datestamp "$ds/results-srcu-lockdep" > $T/srcu_lockdep.sh.out 2>&1
464	retcode=$?
465	cp $T/srcu_lockdep.sh.out "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep/log"
466	if test "$retcode" -eq 0
467	then
468		echo "srcu_lockdep($retcode)" "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep" >> $T/successes
469		echo Success >> "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep/log"
470	else
471		echo "srcu_lockdep($retcode)" "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep" >> $T/failures
472		echo " --- srcu_lockdep Test Summary:" >> "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep/log"
473		echo " --- Summary: Exit code $retcode from srcu_lockdep.sh, see ds/results-srcu-lockdep" >> "tools/testing/selftests/rcutorture/res/$ds/results-srcu-lockdep/log"
474	fi
475fi
476
477if test "$do_refscale" = yes
478then
479	primlist="`grep '\.name[ 	]*=' kernel/rcu/refscale.c | sed -e 's/^[^"]*"//' -e 's/".*$//'`"
480else
481	primlist=
482fi
483firsttime=1
484do_kasan_save="$do_kasan"
485do_kcsan_save="$do_kcsan"
486for prim in $primlist
487do
488	if test -n "$firsttime"
489	then
490		torture_bootargs="refscale.scale_type="$prim" refscale.nreaders=$SCALE_ALLOTED_CPUS refscale.loops=10000 refscale.holdoff=20 torture.disable_onoff_at_boot"
491		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=$SCALE_ALLOTED_CPUS" --bootargs "refscale.verbose_batched=$VERBOSE_BATCH_CPUS torture.verbose_sleep_frequency=8 torture.verbose_sleep_duration=$VERBOSE_BATCH_CPUS" --trust-make
492		mv $T/last-resdir-nodebug $T/first-resdir-nodebug || :
493		if test -f "$T/last-resdir-kasan"
494		then
495			mv $T/last-resdir-kasan $T/first-resdir-kasan || :
496		fi
497		if test -f "$T/last-resdir-kcsan"
498		then
499			mv $T/last-resdir-kcsan $T/first-resdir-kcsan || :
500		fi
501		firsttime=
502		do_kasan=
503		do_kcsan=
504	else
505		torture_bootargs=
506		for i in $T/first-resdir-*
507		do
508			case "$i" in
509			*-nodebug)
510				torture_suffix=
511				;;
512			*-kasan)
513				torture_suffix="-kasan"
514				;;
515			*-kcsan)
516				torture_suffix="-kcsan"
517				;;
518			esac
519			torture_set "refscale-$prim$torture_suffix" tools/testing/selftests/rcutorture/bin/kvm-again.sh "`cat "$i"`" --duration 5 --bootargs "refscale.scale_type=$prim"
520		done
521	fi
522done
523do_kasan="$do_kasan_save"
524do_kcsan="$do_kcsan_save"
525
526if test "$do_rcuscale" = yes
527then
528	primlist="`grep '\.name[ 	]*=' kernel/rcu/rcuscale.c | sed -e 's/^[^"]*"//' -e 's/".*$//'`"
529else
530	primlist=
531fi
532firsttime=1
533do_kasan_save="$do_kasan"
534do_kcsan_save="$do_kcsan"
535for prim in $primlist
536do
537	if test -n "$firsttime"
538	then
539		torture_bootargs="rcuscale.scale_type="$prim" rcuscale.nwriters=$SCALE_ALLOTED_CPUS rcuscale.holdoff=20 torture.disable_onoff_at_boot"
540		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=$SCALE_ALLOTED_CPUS" --trust-make
541		mv $T/last-resdir-nodebug $T/first-resdir-nodebug || :
542		if test -f "$T/last-resdir-kasan"
543		then
544			mv $T/last-resdir-kasan $T/first-resdir-kasan || :
545		fi
546		if test -f "$T/last-resdir-kcsan"
547		then
548			mv $T/last-resdir-kcsan $T/first-resdir-kcsan || :
549		fi
550		firsttime=
551		do_kasan=
552		do_kcsan=
553	else
554		torture_bootargs=
555		for i in $T/first-resdir-*
556		do
557			case "$i" in
558			*-nodebug)
559				torture_suffix=
560				;;
561			*-kasan)
562				torture_suffix="-kasan"
563				;;
564			*-kcsan)
565				torture_suffix="-kcsan"
566				;;
567			esac
568			torture_set "rcuscale-$prim$torture_suffix" tools/testing/selftests/rcutorture/bin/kvm-again.sh "`cat "$i"`" --duration 5 --bootargs "rcuscale.scale_type=$prim"
569		done
570	fi
571done
572do_kasan="$do_kasan_save"
573do_kcsan="$do_kcsan_save"
574
575if test "$do_kvfree" = "yes"
576then
577	torture_bootargs="rcuscale.kfree_rcu_test=1 rcuscale.kfree_nthreads=16 rcuscale.holdoff=20 rcuscale.kfree_loops=10000 torture.disable_onoff_at_boot"
578	torture_set "rcuscale-kvfree" tools/testing/selftests/rcutorture/bin/kvm.sh --torture rcuscale --allcpus --duration $duration_rcutorture --kconfig "CONFIG_NR_CPUS=$SCALE_ALLOTED_CPUS" --memory 2G --trust-make
579fi
580
581if test "$do_clocksourcewd" = "yes"
582then
583	torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog"
584	torture_set "clocksourcewd-1" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make
585
586	torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog"
587	torture_set "clocksourcewd-2" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make
588
589	# In case our work is already done...
590	if test "$do_rcutorture" != "yes"
591	then
592		torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog"
593		torture_set "clocksourcewd-3" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --trust-make
594	fi
595fi
596
597echo " --- " $scriptname $args
598echo " --- " Done `date` | tee -a $T/log
599ret=0
600nsuccesses=0
601echo SUCCESSES: | tee -a $T/log
602if test -s "$T/successes"
603then
604	cat "$T/successes" | tee -a $T/log
605	nsuccesses="`wc -l "$T/successes" | awk '{ print $1 }'`"
606fi
607nfailures=0
608echo FAILURES: | tee -a $T/log
609if test -s "$T/failures"
610then
611	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"
612	nfailures="`wc -l "$T/failures" | awk '{ print $1 }'`"
613	grep "^  Summary: " "$T/failuresum" |
614		grep -v '^  Summary: Bugs: [0-9]* (all bugs kcsan)$' > "$T/nonkcsan"
615	if test -s "$T/nonkcsan"
616	then
617		nonkcsanbug="yes"
618	fi
619	ret=2
620fi
621if test "$do_kcsan" = "yes"
622then
623	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
624fi
625echo Started at $startdate, ended at `date`, duration `get_starttime_duration $starttime`. | tee -a $T/log
626echo Summary: Successes: $nsuccesses Failures: $nfailures. | tee -a $T/log
627tdir="`cat $T/successes $T/failures | head -1 | awk '{ print $NF }' | sed -e 's,/[^/]\+/*$,,'`"
628find "$tdir" -name 'ConfigFragment.diags' -print > $T/configerrors
629find "$tdir" -name 'Make.out.diags' -print > $T/builderrors
630if test -s "$T/configerrors"
631then
632	echo "  Scenarios with .config errors: `wc -l "$T/configerrors" | awk '{ print $1 }'`"
633	nonkcsanbug="yes"
634fi
635if test -s "$T/builderrors"
636then
637	echo "  Scenarios with build errors: `wc -l "$T/builderrors" | awk '{ print $1 }'`"
638	nonkcsanbug="yes"
639fi
640if test -z "$nonkcsanbug" && test -s "$T/failuresum"
641then
642	echo "  All bugs were KCSAN failures."
643fi
644if test -n "$tdir" && test $compress_concurrency -gt 0
645then
646	# KASAN vmlinux files can approach 1GB in size, so compress them.
647	echo Looking for K[AC]SAN files to compress: `date` > "$tdir/log-xz" 2>&1
648	find "$tdir" -type d -name '*-k[ac]san' -print > $T/xz-todo-all
649	find "$tdir" -type f -name 're-run' -print | sed -e 's,/re-run,,' |
650		grep -e '-k[ac]san$' > $T/xz-todo-copy
651	sort $T/xz-todo-all $T/xz-todo-copy | uniq -u > $T/xz-todo
652	ncompresses=0
653	batchno=1
654	if test -s $T/xz-todo
655	then
656		for i in `cat $T/xz-todo`
657		do
658			find $i -name 'vmlinux*' -print
659		done | wc -l | awk '{ print $1 }' > $T/xz-todo-count
660		n2compress="`cat $T/xz-todo-count`"
661		echo Size before compressing $n2compress files: `du -sh $tdir | awk '{ print $1 }'` `date` 2>&1 | tee -a "$tdir/log-xz" | tee -a $T/log
662		for i in `cat $T/xz-todo`
663		do
664			echo Compressing vmlinux files in ${i}: `date` >> "$tdir/log-xz" 2>&1
665			for j in $i/*/vmlinux
666			do
667				xz "$j" >> "$tdir/log-xz" 2>&1 &
668				ncompresses=$((ncompresses+1))
669				if test $ncompresses -ge $compress_concurrency
670				then
671					echo Waiting for batch $batchno of $ncompresses compressions `date` | tee -a "$tdir/log-xz" | tee -a $T/log
672					wait
673					ncompresses=0
674					batchno=$((batchno+1))
675				fi
676			done
677		done
678		if test $ncompresses -gt 0
679		then
680			echo Waiting for final batch $batchno of $ncompresses compressions `date` | tee -a "$tdir/log-xz" | tee -a $T/log
681		fi
682		wait
683		if test -s $T/xz-todo-copy
684		then
685			# The trick here is that we need corresponding
686			# vmlinux files from corresponding scenarios.
687			echo Linking vmlinux.xz files to re-use scenarios `date` | tee -a "$tdir/log-xz" | tee -a $T/log
688			dirstash="`pwd`"
689			for i in `cat $T/xz-todo-copy`
690			do
691				cd $i
692				find . -name vmlinux -print > $T/xz-todo-copy-vmlinux
693				for v in `cat $T/xz-todo-copy-vmlinux`
694				do
695					rm -f "$v"
696					cp -l `cat $i/re-run`/"$i/$v".xz "`dirname "$v"`"
697				done
698				cd "$dirstash"
699			done
700		fi
701		echo Size after compressing $n2compress files: `du -sh $tdir | awk '{ print $1 }'` `date` 2>&1 | tee -a "$tdir/log-xz" | tee -a $T/log
702		echo Total duration `get_starttime_duration $starttime`. | tee -a $T/log
703	else
704		echo No compression needed: `date` >> "$tdir/log-xz" 2>&1
705	fi
706fi
707if test -n "$tdir"
708then
709	cp $T/log "$tdir"
710fi
711exit $ret
712