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