xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/rcutorture/bin/kvm.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/bash
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0+
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# Run a series of tests under KVM.  By default, this series is specified
5*4882a593Smuzhiyun# by the relevant CFLIST file, but can be overridden by the --configs
6*4882a593Smuzhiyun# command-line argument.
7*4882a593Smuzhiyun#
8*4882a593Smuzhiyun# Usage: kvm.sh [ options ]
9*4882a593Smuzhiyun#
10*4882a593Smuzhiyun# Copyright (C) IBM Corporation, 2011
11*4882a593Smuzhiyun#
12*4882a593Smuzhiyun# Authors: Paul E. McKenney <paulmck@linux.ibm.com>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyunscriptname=$0
15*4882a593Smuzhiyunargs="$*"
16*4882a593Smuzhiyun
17*4882a593SmuzhiyunT=${TMPDIR-/tmp}/kvm.sh.$$
18*4882a593Smuzhiyuntrap 'rm -rf $T' 0
19*4882a593Smuzhiyunmkdir $T
20*4882a593Smuzhiyun
21*4882a593Smuzhiyuncd `dirname $scriptname`/../../../../../
22*4882a593Smuzhiyun
23*4882a593Smuzhiyundur=$((30*60))
24*4882a593Smuzhiyundryrun=""
25*4882a593SmuzhiyunKVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM
26*4882a593SmuzhiyunPATH=${KVM}/bin:$PATH; export PATH
27*4882a593Smuzhiyun. functions.sh
28*4882a593Smuzhiyun
29*4882a593SmuzhiyunTORTURE_ALLOTED_CPUS="`identify_qemu_vcpus`"
30*4882a593SmuzhiyunTORTURE_DEFCONFIG=defconfig
31*4882a593SmuzhiyunTORTURE_BOOT_IMAGE=""
32*4882a593SmuzhiyunTORTURE_INITRD="$KVM/initrd"; export TORTURE_INITRD
33*4882a593SmuzhiyunTORTURE_KCONFIG_ARG=""
34*4882a593SmuzhiyunTORTURE_KCONFIG_GDB_ARG=""
35*4882a593SmuzhiyunTORTURE_BOOT_GDB_ARG=""
36*4882a593SmuzhiyunTORTURE_QEMU_GDB_ARG=""
37*4882a593SmuzhiyunTORTURE_KCONFIG_KASAN_ARG=""
38*4882a593SmuzhiyunTORTURE_KCONFIG_KCSAN_ARG=""
39*4882a593SmuzhiyunTORTURE_KMAKE_ARG=""
40*4882a593SmuzhiyunTORTURE_QEMU_MEM=512
41*4882a593SmuzhiyunTORTURE_SHUTDOWN_GRACE=180
42*4882a593SmuzhiyunTORTURE_SUITE=rcu
43*4882a593SmuzhiyunTORTURE_TRUST_MAKE=""
44*4882a593Smuzhiyunresdir=""
45*4882a593Smuzhiyunconfigs=""
46*4882a593Smuzhiyuncpus=0
47*4882a593Smuzhiyunds=`date +%Y.%m.%d-%H.%M.%S`
48*4882a593Smuzhiyunjitter="-1"
49*4882a593Smuzhiyun
50*4882a593Smuzhiyunusage () {
51*4882a593Smuzhiyun	echo "Usage: $scriptname optional arguments:"
52*4882a593Smuzhiyun	echo "       --allcpus"
53*4882a593Smuzhiyun	echo "       --bootargs kernel-boot-arguments"
54*4882a593Smuzhiyun	echo "       --bootimage relative-path-to-kernel-boot-image"
55*4882a593Smuzhiyun	echo "       --buildonly"
56*4882a593Smuzhiyun	echo "       --configs \"config-file list w/ repeat factor (3*TINY01)\""
57*4882a593Smuzhiyun	echo "       --cpus N"
58*4882a593Smuzhiyun	echo "       --datestamp string"
59*4882a593Smuzhiyun	echo "       --defconfig string"
60*4882a593Smuzhiyun	echo "       --dryrun sched|script"
61*4882a593Smuzhiyun	echo "       --duration minutes"
62*4882a593Smuzhiyun	echo "       --gdb"
63*4882a593Smuzhiyun	echo "       --help"
64*4882a593Smuzhiyun	echo "       --interactive"
65*4882a593Smuzhiyun	echo "       --jitter N [ maxsleep (us) [ maxspin (us) ] ]"
66*4882a593Smuzhiyun	echo "       --kconfig Kconfig-options"
67*4882a593Smuzhiyun	echo "       --kmake-arg kernel-make-arguments"
68*4882a593Smuzhiyun	echo "       --mac nn:nn:nn:nn:nn:nn"
69*4882a593Smuzhiyun	echo "       --memory megabytes|nnnG"
70*4882a593Smuzhiyun	echo "       --no-initrd"
71*4882a593Smuzhiyun	echo "       --qemu-args qemu-arguments"
72*4882a593Smuzhiyun	echo "       --qemu-cmd qemu-system-..."
73*4882a593Smuzhiyun	echo "       --results absolute-pathname"
74*4882a593Smuzhiyun	echo "       --torture lock|rcu|rcuscale|refscale|scf"
75*4882a593Smuzhiyun	echo "       --trust-make"
76*4882a593Smuzhiyun	exit 1
77*4882a593Smuzhiyun}
78*4882a593Smuzhiyun
79*4882a593Smuzhiyunwhile test $# -gt 0
80*4882a593Smuzhiyundo
81*4882a593Smuzhiyun	case "$1" in
82*4882a593Smuzhiyun	--allcpus)
83*4882a593Smuzhiyun		cpus=$TORTURE_ALLOTED_CPUS
84*4882a593Smuzhiyun		max_cpus=$TORTURE_ALLOTED_CPUS
85*4882a593Smuzhiyun		;;
86*4882a593Smuzhiyun	--bootargs|--bootarg)
87*4882a593Smuzhiyun		checkarg --bootargs "(list of kernel boot arguments)" "$#" "$2" '.*' '^--'
88*4882a593Smuzhiyun		TORTURE_BOOTARGS="$2"
89*4882a593Smuzhiyun		shift
90*4882a593Smuzhiyun		;;
91*4882a593Smuzhiyun	--bootimage)
92*4882a593Smuzhiyun		checkarg --bootimage "(relative path to kernel boot image)" "$#" "$2" '[a-zA-Z0-9][a-zA-Z0-9_]*' '^--'
93*4882a593Smuzhiyun		TORTURE_BOOT_IMAGE="$2"
94*4882a593Smuzhiyun		shift
95*4882a593Smuzhiyun		;;
96*4882a593Smuzhiyun	--buildonly)
97*4882a593Smuzhiyun		TORTURE_BUILDONLY=1
98*4882a593Smuzhiyun		;;
99*4882a593Smuzhiyun	--configs|--config)
100*4882a593Smuzhiyun		checkarg --configs "(list of config files)" "$#" "$2" '^[^/]*$' '^--'
101*4882a593Smuzhiyun		configs="$2"
102*4882a593Smuzhiyun		shift
103*4882a593Smuzhiyun		;;
104*4882a593Smuzhiyun	--cpus)
105*4882a593Smuzhiyun		checkarg --cpus "(number)" "$#" "$2" '^[0-9]*$' '^--'
106*4882a593Smuzhiyun		cpus=$2
107*4882a593Smuzhiyun		TORTURE_ALLOTED_CPUS="$2"
108*4882a593Smuzhiyun		max_cpus="`identify_qemu_vcpus`"
109*4882a593Smuzhiyun		if test "$TORTURE_ALLOTED_CPUS" -gt "$max_cpus"
110*4882a593Smuzhiyun		then
111*4882a593Smuzhiyun			TORTURE_ALLOTED_CPUS=$max_cpus
112*4882a593Smuzhiyun		fi
113*4882a593Smuzhiyun		shift
114*4882a593Smuzhiyun		;;
115*4882a593Smuzhiyun	--datestamp)
116*4882a593Smuzhiyun		checkarg --datestamp "(relative pathname)" "$#" "$2" '^[^/]*$' '^--'
117*4882a593Smuzhiyun		ds=$2
118*4882a593Smuzhiyun		shift
119*4882a593Smuzhiyun		;;
120*4882a593Smuzhiyun	--defconfig)
121*4882a593Smuzhiyun		checkarg --defconfig "defconfigtype" "$#" "$2" '^[^/][^/]*$' '^--'
122*4882a593Smuzhiyun		TORTURE_DEFCONFIG=$2
123*4882a593Smuzhiyun		shift
124*4882a593Smuzhiyun		;;
125*4882a593Smuzhiyun	--dryrun)
126*4882a593Smuzhiyun		checkarg --dryrun "sched|script" $# "$2" 'sched\|script' '^--'
127*4882a593Smuzhiyun		dryrun=$2
128*4882a593Smuzhiyun		shift
129*4882a593Smuzhiyun		;;
130*4882a593Smuzhiyun	--duration)
131*4882a593Smuzhiyun		checkarg --duration "(minutes)" $# "$2" '^[0-9]*$' '^error'
132*4882a593Smuzhiyun		dur=$(($2*60))
133*4882a593Smuzhiyun		shift
134*4882a593Smuzhiyun		;;
135*4882a593Smuzhiyun	--gdb)
136*4882a593Smuzhiyun		TORTURE_KCONFIG_GDB_ARG="CONFIG_DEBUG_INFO=y"; export TORTURE_KCONFIG_GDB_ARG
137*4882a593Smuzhiyun		TORTURE_BOOT_GDB_ARG="nokaslr"; export TORTURE_BOOT_GDB_ARG
138*4882a593Smuzhiyun		TORTURE_QEMU_GDB_ARG="-s -S"; export TORTURE_QEMU_GDB_ARG
139*4882a593Smuzhiyun		;;
140*4882a593Smuzhiyun	--help|-h)
141*4882a593Smuzhiyun		usage
142*4882a593Smuzhiyun		;;
143*4882a593Smuzhiyun	--interactive)
144*4882a593Smuzhiyun		TORTURE_QEMU_INTERACTIVE=1; export TORTURE_QEMU_INTERACTIVE
145*4882a593Smuzhiyun		;;
146*4882a593Smuzhiyun	--jitter)
147*4882a593Smuzhiyun		checkarg --jitter "(# threads [ sleep [ spin ] ])" $# "$2" '^-\{,1\}[0-9]\+\( \+[0-9]\+\)\{,2\} *$' '^error$'
148*4882a593Smuzhiyun		jitter="$2"
149*4882a593Smuzhiyun		shift
150*4882a593Smuzhiyun		;;
151*4882a593Smuzhiyun	--kconfig)
152*4882a593Smuzhiyun		checkarg --kconfig "(Kconfig options)" $# "$2" '^CONFIG_[A-Z0-9_]\+=\([ynm]\|[0-9]\+\)\( CONFIG_[A-Z0-9_]\+=\([ynm]\|[0-9]\+\)\)*$' '^error$'
153*4882a593Smuzhiyun		TORTURE_KCONFIG_ARG="$2"
154*4882a593Smuzhiyun		shift
155*4882a593Smuzhiyun		;;
156*4882a593Smuzhiyun	--kasan)
157*4882a593Smuzhiyun		TORTURE_KCONFIG_KASAN_ARG="CONFIG_DEBUG_INFO=y CONFIG_KASAN=y"; export TORTURE_KCONFIG_KASAN_ARG
158*4882a593Smuzhiyun		;;
159*4882a593Smuzhiyun	--kcsan)
160*4882a593Smuzhiyun		TORTURE_KCONFIG_KCSAN_ARG="CONFIG_DEBUG_INFO=y CONFIG_KCSAN=y CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=n CONFIG_KCSAN_REPORT_ONCE_IN_MS=100000 CONFIG_KCSAN_VERBOSE=y CONFIG_KCSAN_INTERRUPT_WATCHER=y"; export TORTURE_KCONFIG_KCSAN_ARG
161*4882a593Smuzhiyun		;;
162*4882a593Smuzhiyun	--kmake-arg)
163*4882a593Smuzhiyun		checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$'
164*4882a593Smuzhiyun		TORTURE_KMAKE_ARG="$2"
165*4882a593Smuzhiyun		shift
166*4882a593Smuzhiyun		;;
167*4882a593Smuzhiyun	--mac)
168*4882a593Smuzhiyun		checkarg --mac "(MAC address)" $# "$2" '^\([0-9a-fA-F]\{2\}:\)\{5\}[0-9a-fA-F]\{2\}$' error
169*4882a593Smuzhiyun		TORTURE_QEMU_MAC=$2
170*4882a593Smuzhiyun		shift
171*4882a593Smuzhiyun		;;
172*4882a593Smuzhiyun	--memory)
173*4882a593Smuzhiyun		checkarg --memory "(memory size)" $# "$2" '^[0-9]\+[MG]\?$' error
174*4882a593Smuzhiyun		TORTURE_QEMU_MEM=$2
175*4882a593Smuzhiyun		shift
176*4882a593Smuzhiyun		;;
177*4882a593Smuzhiyun	--no-initrd)
178*4882a593Smuzhiyun		TORTURE_INITRD=""; export TORTURE_INITRD
179*4882a593Smuzhiyun		;;
180*4882a593Smuzhiyun	--qemu-args|--qemu-arg)
181*4882a593Smuzhiyun		checkarg --qemu-args "(qemu arguments)" $# "$2" '^-' '^error'
182*4882a593Smuzhiyun		TORTURE_QEMU_ARG="$2"
183*4882a593Smuzhiyun		shift
184*4882a593Smuzhiyun		;;
185*4882a593Smuzhiyun	--qemu-cmd)
186*4882a593Smuzhiyun		checkarg --qemu-cmd "(qemu-system-...)" $# "$2" 'qemu-system-' '^--'
187*4882a593Smuzhiyun		TORTURE_QEMU_CMD="$2"
188*4882a593Smuzhiyun		shift
189*4882a593Smuzhiyun		;;
190*4882a593Smuzhiyun	--results)
191*4882a593Smuzhiyun		checkarg --results "(absolute pathname)" "$#" "$2" '^/' '^error'
192*4882a593Smuzhiyun		resdir=$2
193*4882a593Smuzhiyun		shift
194*4882a593Smuzhiyun		;;
195*4882a593Smuzhiyun	--shutdown-grace)
196*4882a593Smuzhiyun		checkarg --shutdown-grace "(seconds)" "$#" "$2" '^[0-9]*$' '^error'
197*4882a593Smuzhiyun		TORTURE_SHUTDOWN_GRACE=$2
198*4882a593Smuzhiyun		shift
199*4882a593Smuzhiyun		;;
200*4882a593Smuzhiyun	--torture)
201*4882a593Smuzhiyun		checkarg --torture "(suite name)" "$#" "$2" '^\(lock\|rcu\|rcuscale\|refscale\|scf\)$' '^--'
202*4882a593Smuzhiyun		TORTURE_SUITE=$2
203*4882a593Smuzhiyun		shift
204*4882a593Smuzhiyun		if test "$TORTURE_SUITE" = rcuscale || test "$TORTURE_SUITE" = refscale
205*4882a593Smuzhiyun		then
206*4882a593Smuzhiyun			# If you really want jitter for refscale or
207*4882a593Smuzhiyun			# rcuscale, specify it after specifying the rcuscale
208*4882a593Smuzhiyun			# or the refscale.  (But why jitter in these cases?)
209*4882a593Smuzhiyun			jitter=0
210*4882a593Smuzhiyun		fi
211*4882a593Smuzhiyun		;;
212*4882a593Smuzhiyun	--trust-make)
213*4882a593Smuzhiyun		TORTURE_TRUST_MAKE="y"
214*4882a593Smuzhiyun		;;
215*4882a593Smuzhiyun	*)
216*4882a593Smuzhiyun		echo Unknown argument $1
217*4882a593Smuzhiyun		usage
218*4882a593Smuzhiyun		;;
219*4882a593Smuzhiyun	esac
220*4882a593Smuzhiyun	shift
221*4882a593Smuzhiyundone
222*4882a593Smuzhiyun
223*4882a593Smuzhiyunif test -z "$TORTURE_INITRD" || tools/testing/selftests/rcutorture/bin/mkinitrd.sh
224*4882a593Smuzhiyunthen
225*4882a593Smuzhiyun	:
226*4882a593Smuzhiyunelse
227*4882a593Smuzhiyun	echo No initrd and unable to create one, aborting test >&2
228*4882a593Smuzhiyun	exit 1
229*4882a593Smuzhiyunfi
230*4882a593Smuzhiyun
231*4882a593SmuzhiyunCONFIGFRAG=${KVM}/configs/${TORTURE_SUITE}; export CONFIGFRAG
232*4882a593Smuzhiyun
233*4882a593Smuzhiyundefaultconfigs="`tr '\012' ' ' < $CONFIGFRAG/CFLIST`"
234*4882a593Smuzhiyunif test -z "$configs"
235*4882a593Smuzhiyunthen
236*4882a593Smuzhiyun	configs=$defaultconfigs
237*4882a593Smuzhiyunfi
238*4882a593Smuzhiyun
239*4882a593Smuzhiyunif test -z "$resdir"
240*4882a593Smuzhiyunthen
241*4882a593Smuzhiyun	resdir=$KVM/res
242*4882a593Smuzhiyunfi
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun# Create a file of test-name/#cpus pairs, sorted by decreasing #cpus.
245*4882a593Smuzhiyunconfigs_derep=
246*4882a593Smuzhiyunfor CF in $configs
247*4882a593Smuzhiyundo
248*4882a593Smuzhiyun	case $CF in
249*4882a593Smuzhiyun	[0-9]\**|[0-9][0-9]\**|[0-9][0-9][0-9]\**)
250*4882a593Smuzhiyun		config_reps=`echo $CF | sed -e 's/\*.*$//'`
251*4882a593Smuzhiyun		CF1=`echo $CF | sed -e 's/^[^*]*\*//'`
252*4882a593Smuzhiyun		;;
253*4882a593Smuzhiyun	*)
254*4882a593Smuzhiyun		config_reps=1
255*4882a593Smuzhiyun		CF1=$CF
256*4882a593Smuzhiyun		;;
257*4882a593Smuzhiyun	esac
258*4882a593Smuzhiyun	for ((cur_rep=0;cur_rep<$config_reps;cur_rep++))
259*4882a593Smuzhiyun	do
260*4882a593Smuzhiyun		configs_derep="$configs_derep $CF1"
261*4882a593Smuzhiyun	done
262*4882a593Smuzhiyundone
263*4882a593Smuzhiyuntouch $T/cfgcpu
264*4882a593Smuzhiyunconfigs_derep="`echo $configs_derep | sed -e "s/\<CFLIST\>/$defaultconfigs/g"`"
265*4882a593Smuzhiyunif test -n "$TORTURE_KCONFIG_GDB_ARG"
266*4882a593Smuzhiyunthen
267*4882a593Smuzhiyun	if test "`echo $configs_derep | wc -w`" -gt 1
268*4882a593Smuzhiyun	then
269*4882a593Smuzhiyun		echo "The --config list is: $configs_derep."
270*4882a593Smuzhiyun		echo "Only one --config permitted with --gdb, terminating."
271*4882a593Smuzhiyun		exit 1
272*4882a593Smuzhiyun	fi
273*4882a593Smuzhiyunfi
274*4882a593Smuzhiyunfor CF1 in $configs_derep
275*4882a593Smuzhiyundo
276*4882a593Smuzhiyun	if test -f "$CONFIGFRAG/$CF1"
277*4882a593Smuzhiyun	then
278*4882a593Smuzhiyun		cpu_count=`configNR_CPUS.sh $CONFIGFRAG/$CF1`
279*4882a593Smuzhiyun		cpu_count=`configfrag_boot_cpus "$TORTURE_BOOTARGS" "$CONFIGFRAG/$CF1" "$cpu_count"`
280*4882a593Smuzhiyun		cpu_count=`configfrag_boot_maxcpus "$TORTURE_BOOTARGS" "$CONFIGFRAG/$CF1" "$cpu_count"`
281*4882a593Smuzhiyun		echo $CF1 $cpu_count >> $T/cfgcpu
282*4882a593Smuzhiyun	else
283*4882a593Smuzhiyun		echo "The --configs file $CF1 does not exist, terminating."
284*4882a593Smuzhiyun		exit 1
285*4882a593Smuzhiyun	fi
286*4882a593Smuzhiyundone
287*4882a593Smuzhiyunsort -k2nr $T/cfgcpu -T="$T" > $T/cfgcpu.sort
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun# Use a greedy bin-packing algorithm, sorting the list accordingly.
290*4882a593Smuzhiyunawk < $T/cfgcpu.sort > $T/cfgcpu.pack -v ncpus=$cpus '
291*4882a593SmuzhiyunBEGIN {
292*4882a593Smuzhiyun	njobs = 0;
293*4882a593Smuzhiyun}
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun{
296*4882a593Smuzhiyun	# Read file of tests and corresponding required numbers of CPUs.
297*4882a593Smuzhiyun	cf[njobs] = $1;
298*4882a593Smuzhiyun	cpus[njobs] = $2;
299*4882a593Smuzhiyun	njobs++;
300*4882a593Smuzhiyun}
301*4882a593Smuzhiyun
302*4882a593SmuzhiyunEND {
303*4882a593Smuzhiyun	batch = 0;
304*4882a593Smuzhiyun	nc = -1;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun	# Each pass through the following loop creates on test batch
307*4882a593Smuzhiyun	# that can be executed concurrently given ncpus.  Note that a
308*4882a593Smuzhiyun	# given test that requires more than the available CPUs will run in
309*4882a593Smuzhiyun	# their own batch.  Such tests just have to make do with what
310*4882a593Smuzhiyun	# is available.
311*4882a593Smuzhiyun	while (nc != ncpus) {
312*4882a593Smuzhiyun		batch++;
313*4882a593Smuzhiyun		nc = ncpus;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun		# Each pass through the following loop considers one
316*4882a593Smuzhiyun		# test for inclusion in the current batch.
317*4882a593Smuzhiyun		for (i = 0; i < njobs; i++) {
318*4882a593Smuzhiyun			if (done[i])
319*4882a593Smuzhiyun				continue; # Already part of a batch.
320*4882a593Smuzhiyun			if (nc >= cpus[i] || nc == ncpus) {
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun				# This test fits into the current batch.
323*4882a593Smuzhiyun				done[i] = batch;
324*4882a593Smuzhiyun				nc -= cpus[i];
325*4882a593Smuzhiyun				if (nc <= 0)
326*4882a593Smuzhiyun					break; # Too-big test in its own batch.
327*4882a593Smuzhiyun			}
328*4882a593Smuzhiyun		}
329*4882a593Smuzhiyun	}
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun	# Dump out the tests in batch order.
332*4882a593Smuzhiyun	for (b = 1; b <= batch; b++)
333*4882a593Smuzhiyun		for (i = 0; i < njobs; i++)
334*4882a593Smuzhiyun			if (done[i] == b)
335*4882a593Smuzhiyun				print cf[i], cpus[i];
336*4882a593Smuzhiyun}'
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun# Generate a script to execute the tests in appropriate batches.
339*4882a593Smuzhiyuncat << ___EOF___ > $T/script
340*4882a593SmuzhiyunCONFIGFRAG="$CONFIGFRAG"; export CONFIGFRAG
341*4882a593SmuzhiyunKVM="$KVM"; export KVM
342*4882a593SmuzhiyunPATH="$PATH"; export PATH
343*4882a593SmuzhiyunTORTURE_ALLOTED_CPUS="$TORTURE_ALLOTED_CPUS"; export TORTURE_ALLOTED_CPUS
344*4882a593SmuzhiyunTORTURE_BOOT_IMAGE="$TORTURE_BOOT_IMAGE"; export TORTURE_BOOT_IMAGE
345*4882a593SmuzhiyunTORTURE_BUILDONLY="$TORTURE_BUILDONLY"; export TORTURE_BUILDONLY
346*4882a593SmuzhiyunTORTURE_DEFCONFIG="$TORTURE_DEFCONFIG"; export TORTURE_DEFCONFIG
347*4882a593SmuzhiyunTORTURE_INITRD="$TORTURE_INITRD"; export TORTURE_INITRD
348*4882a593SmuzhiyunTORTURE_KCONFIG_ARG="$TORTURE_KCONFIG_ARG"; export TORTURE_KCONFIG_ARG
349*4882a593SmuzhiyunTORTURE_KCONFIG_GDB_ARG="$TORTURE_KCONFIG_GDB_ARG"; export TORTURE_KCONFIG_GDB_ARG
350*4882a593SmuzhiyunTORTURE_BOOT_GDB_ARG="$TORTURE_BOOT_GDB_ARG"; export TORTURE_BOOT_GDB_ARG
351*4882a593SmuzhiyunTORTURE_QEMU_GDB_ARG="$TORTURE_QEMU_GDB_ARG"; export TORTURE_QEMU_GDB_ARG
352*4882a593SmuzhiyunTORTURE_KCONFIG_KASAN_ARG="$TORTURE_KCONFIG_KASAN_ARG"; export TORTURE_KCONFIG_KASAN_ARG
353*4882a593SmuzhiyunTORTURE_KCONFIG_KCSAN_ARG="$TORTURE_KCONFIG_KCSAN_ARG"; export TORTURE_KCONFIG_KCSAN_ARG
354*4882a593SmuzhiyunTORTURE_KMAKE_ARG="$TORTURE_KMAKE_ARG"; export TORTURE_KMAKE_ARG
355*4882a593SmuzhiyunTORTURE_QEMU_CMD="$TORTURE_QEMU_CMD"; export TORTURE_QEMU_CMD
356*4882a593SmuzhiyunTORTURE_QEMU_INTERACTIVE="$TORTURE_QEMU_INTERACTIVE"; export TORTURE_QEMU_INTERACTIVE
357*4882a593SmuzhiyunTORTURE_QEMU_MAC="$TORTURE_QEMU_MAC"; export TORTURE_QEMU_MAC
358*4882a593SmuzhiyunTORTURE_QEMU_MEM="$TORTURE_QEMU_MEM"; export TORTURE_QEMU_MEM
359*4882a593SmuzhiyunTORTURE_SHUTDOWN_GRACE="$TORTURE_SHUTDOWN_GRACE"; export TORTURE_SHUTDOWN_GRACE
360*4882a593SmuzhiyunTORTURE_SUITE="$TORTURE_SUITE"; export TORTURE_SUITE
361*4882a593SmuzhiyunTORTURE_TRUST_MAKE="$TORTURE_TRUST_MAKE"; export TORTURE_TRUST_MAKE
362*4882a593Smuzhiyunif ! test -e $resdir
363*4882a593Smuzhiyunthen
364*4882a593Smuzhiyun	mkdir -p "$resdir" || :
365*4882a593Smuzhiyunfi
366*4882a593Smuzhiyunmkdir $resdir/$ds
367*4882a593SmuzhiyunTORTURE_RESDIR="$resdir/$ds"; export TORTURE_RESDIR
368*4882a593SmuzhiyunTORTURE_STOPFILE="$resdir/$ds/STOP"; export TORTURE_STOPFILE
369*4882a593Smuzhiyunecho Results directory: $resdir/$ds
370*4882a593Smuzhiyunecho $scriptname $args
371*4882a593Smuzhiyuntouch $resdir/$ds/log
372*4882a593Smuzhiyunecho $scriptname $args >> $resdir/$ds/log
373*4882a593Smuzhiyunecho ${TORTURE_SUITE} > $resdir/$ds/TORTURE_SUITE
374*4882a593Smuzhiyunpwd > $resdir/$ds/testid.txt
375*4882a593Smuzhiyunif test -d .git
376*4882a593Smuzhiyunthen
377*4882a593Smuzhiyun	git status >> $resdir/$ds/testid.txt
378*4882a593Smuzhiyun	git rev-parse HEAD >> $resdir/$ds/testid.txt
379*4882a593Smuzhiyun	git diff HEAD >> $resdir/$ds/testid.txt
380*4882a593Smuzhiyunfi
381*4882a593Smuzhiyun___EOF___
382*4882a593Smuzhiyunawk < $T/cfgcpu.pack \
383*4882a593Smuzhiyun	-v TORTURE_BUILDONLY="$TORTURE_BUILDONLY" \
384*4882a593Smuzhiyun	-v CONFIGDIR="$CONFIGFRAG/" \
385*4882a593Smuzhiyun	-v KVM="$KVM" \
386*4882a593Smuzhiyun	-v ncpus=$cpus \
387*4882a593Smuzhiyun	-v jitter="$jitter" \
388*4882a593Smuzhiyun	-v rd=$resdir/$ds/ \
389*4882a593Smuzhiyun	-v dur=$dur \
390*4882a593Smuzhiyun	-v TORTURE_QEMU_ARG="$TORTURE_QEMU_ARG" \
391*4882a593Smuzhiyun	-v TORTURE_BOOTARGS="$TORTURE_BOOTARGS" \
392*4882a593Smuzhiyun'BEGIN {
393*4882a593Smuzhiyun	i = 0;
394*4882a593Smuzhiyun}
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun{
397*4882a593Smuzhiyun	cf[i] = $1;
398*4882a593Smuzhiyun	cpus[i] = $2;
399*4882a593Smuzhiyun	i++;
400*4882a593Smuzhiyun}
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun# Dump out the scripting required to run one test batch.
403*4882a593Smuzhiyunfunction dump(first, pastlast, batchnum)
404*4882a593Smuzhiyun{
405*4882a593Smuzhiyun	print "echo ----Start batch " batchnum ": `date` | tee -a " rd "log";
406*4882a593Smuzhiyun	print "needqemurun="
407*4882a593Smuzhiyun	jn=1
408*4882a593Smuzhiyun	for (j = first; j < pastlast; j++) {
409*4882a593Smuzhiyun		builddir=KVM "/b" j - first + 1
410*4882a593Smuzhiyun		cpusr[jn] = cpus[j];
411*4882a593Smuzhiyun		if (cfrep[cf[j]] == "") {
412*4882a593Smuzhiyun			cfr[jn] = cf[j];
413*4882a593Smuzhiyun			cfrep[cf[j]] = 1;
414*4882a593Smuzhiyun		} else {
415*4882a593Smuzhiyun			cfrep[cf[j]]++;
416*4882a593Smuzhiyun			cfr[jn] = cf[j] "." cfrep[cf[j]];
417*4882a593Smuzhiyun		}
418*4882a593Smuzhiyun		if (cpusr[jn] > ncpus && ncpus != 0)
419*4882a593Smuzhiyun			ovf = "-ovf";
420*4882a593Smuzhiyun		else
421*4882a593Smuzhiyun			ovf = "";
422*4882a593Smuzhiyun		print "echo ", cfr[jn], cpusr[jn] ovf ": Starting build. `date` | tee -a " rd "log";
423*4882a593Smuzhiyun		print "rm -f " builddir ".*";
424*4882a593Smuzhiyun		print "touch " builddir ".wait";
425*4882a593Smuzhiyun		print "mkdir " rd cfr[jn] " || :";
426*4882a593Smuzhiyun		print "kvm-test-1-run.sh " CONFIGDIR cf[j], builddir, rd cfr[jn], dur " \"" TORTURE_QEMU_ARG "\" \"" TORTURE_BOOTARGS "\" > " rd cfr[jn]  "/kvm-test-1-run.sh.out 2>&1 &"
427*4882a593Smuzhiyun		print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date` | tee -a " rd "log";
428*4882a593Smuzhiyun		print "while test -f " builddir ".wait"
429*4882a593Smuzhiyun		print "do"
430*4882a593Smuzhiyun		print "\tsleep 1"
431*4882a593Smuzhiyun		print "done"
432*4882a593Smuzhiyun		print "echo ", cfr[jn], cpusr[jn] ovf ": Build complete. `date` | tee -a " rd "log";
433*4882a593Smuzhiyun		jn++;
434*4882a593Smuzhiyun	}
435*4882a593Smuzhiyun	for (j = 1; j < jn; j++) {
436*4882a593Smuzhiyun		builddir=KVM "/b" j
437*4882a593Smuzhiyun		print "rm -f " builddir ".ready"
438*4882a593Smuzhiyun		print "if test -f \"" rd cfr[j] "/builtkernel\""
439*4882a593Smuzhiyun		print "then"
440*4882a593Smuzhiyun		print "\techo ----", cfr[j], cpusr[j] ovf ": Kernel present. `date` | tee -a " rd "log";
441*4882a593Smuzhiyun		print "\tneedqemurun=1"
442*4882a593Smuzhiyun		print "fi"
443*4882a593Smuzhiyun	}
444*4882a593Smuzhiyun	njitter = 0;
445*4882a593Smuzhiyun	split(jitter, ja);
446*4882a593Smuzhiyun	if (ja[1] == -1 && ncpus == 0)
447*4882a593Smuzhiyun		njitter = 1;
448*4882a593Smuzhiyun	else if (ja[1] == -1)
449*4882a593Smuzhiyun		njitter = ncpus;
450*4882a593Smuzhiyun	else
451*4882a593Smuzhiyun		njitter = ja[1];
452*4882a593Smuzhiyun	if (TORTURE_BUILDONLY && njitter != 0) {
453*4882a593Smuzhiyun		njitter = 0;
454*4882a593Smuzhiyun		print "echo Build-only run, so suppressing jitter | tee -a " rd "log"
455*4882a593Smuzhiyun	}
456*4882a593Smuzhiyun	if (TORTURE_BUILDONLY) {
457*4882a593Smuzhiyun		print "needqemurun="
458*4882a593Smuzhiyun	}
459*4882a593Smuzhiyun	print "if test -n \"$needqemurun\""
460*4882a593Smuzhiyun	print "then"
461*4882a593Smuzhiyun	print "\techo ---- Starting kernels. `date` | tee -a " rd "log";
462*4882a593Smuzhiyun	for (j = 0; j < njitter; j++)
463*4882a593Smuzhiyun		print "\tjitter.sh " j " " dur " " ja[2] " " ja[3] "&"
464*4882a593Smuzhiyun	print "\twait"
465*4882a593Smuzhiyun	print "\techo ---- All kernel runs complete. `date` | tee -a " rd "log";
466*4882a593Smuzhiyun	print "else"
467*4882a593Smuzhiyun	print "\twait"
468*4882a593Smuzhiyun	print "\techo ---- No kernel runs. `date` | tee -a " rd "log";
469*4882a593Smuzhiyun	print "fi"
470*4882a593Smuzhiyun	for (j = 1; j < jn; j++) {
471*4882a593Smuzhiyun		builddir=KVM "/b" j
472*4882a593Smuzhiyun		print "echo ----", cfr[j], cpusr[j] ovf ": Build/run results: | tee -a " rd "log";
473*4882a593Smuzhiyun		print "cat " rd cfr[j]  "/kvm-test-1-run.sh.out | tee -a " rd "log";
474*4882a593Smuzhiyun	}
475*4882a593Smuzhiyun}
476*4882a593Smuzhiyun
477*4882a593SmuzhiyunEND {
478*4882a593Smuzhiyun	njobs = i;
479*4882a593Smuzhiyun	nc = ncpus;
480*4882a593Smuzhiyun	first = 0;
481*4882a593Smuzhiyun	batchnum = 1;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun	# Each pass through the following loop considers one test.
484*4882a593Smuzhiyun	for (i = 0; i < njobs; i++) {
485*4882a593Smuzhiyun		if (ncpus == 0) {
486*4882a593Smuzhiyun			# Sequential test specified, each test its own batch.
487*4882a593Smuzhiyun			dump(i, i + 1, batchnum);
488*4882a593Smuzhiyun			first = i;
489*4882a593Smuzhiyun			batchnum++;
490*4882a593Smuzhiyun		} else if (nc < cpus[i] && i != 0) {
491*4882a593Smuzhiyun			# Out of CPUs, dump out a batch.
492*4882a593Smuzhiyun			dump(first, i, batchnum);
493*4882a593Smuzhiyun			first = i;
494*4882a593Smuzhiyun			nc = ncpus;
495*4882a593Smuzhiyun			batchnum++;
496*4882a593Smuzhiyun		}
497*4882a593Smuzhiyun		# Account for the CPUs needed by the current test.
498*4882a593Smuzhiyun		nc -= cpus[i];
499*4882a593Smuzhiyun	}
500*4882a593Smuzhiyun	# Dump the last batch.
501*4882a593Smuzhiyun	if (ncpus != 0)
502*4882a593Smuzhiyun		dump(first, i, batchnum);
503*4882a593Smuzhiyun}' >> $T/script
504*4882a593Smuzhiyun
505*4882a593Smuzhiyuncat << ___EOF___ >> $T/script
506*4882a593Smuzhiyunecho
507*4882a593Smuzhiyunecho
508*4882a593Smuzhiyunecho " --- `date` Test summary:"
509*4882a593Smuzhiyunecho Results directory: $resdir/$ds
510*4882a593Smuzhiyunkcsan-collapse.sh $resdir/$ds
511*4882a593Smuzhiyunkvm-recheck.sh $resdir/$ds
512*4882a593Smuzhiyun___EOF___
513*4882a593Smuzhiyun
514*4882a593Smuzhiyunif test "$dryrun" = script
515*4882a593Smuzhiyunthen
516*4882a593Smuzhiyun	cat $T/script
517*4882a593Smuzhiyun	exit 0
518*4882a593Smuzhiyunelif test "$dryrun" = sched
519*4882a593Smuzhiyunthen
520*4882a593Smuzhiyun	# Extract the test run schedule from the script.
521*4882a593Smuzhiyun	egrep 'Start batch|Starting build\.' $T/script |
522*4882a593Smuzhiyun		grep -v ">>" |
523*4882a593Smuzhiyun		sed -e 's/:.*$//' -e 's/^echo //'
524*4882a593Smuzhiyun	exit 0
525*4882a593Smuzhiyunelse
526*4882a593Smuzhiyun	# Not a dryrun, so run the script.
527*4882a593Smuzhiyun	sh $T/script
528*4882a593Smuzhiyunfi
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun# Tracing: trace_event=rcu:rcu_grace_period,rcu:rcu_future_grace_period,rcu:rcu_grace_period_init,rcu:rcu_nocb_wake,rcu:rcu_preempt_task,rcu:rcu_unlock_preempted_task,rcu:rcu_quiescent_state_report,rcu:rcu_fqs,rcu:rcu_callback,rcu:rcu_kfree_callback,rcu:rcu_batch_start,rcu:rcu_invoke_callback,rcu:rcu_invoke_kfree_callback,rcu:rcu_batch_end,rcu:rcu_torture_read,rcu:rcu_barrier
531*4882a593Smuzhiyun# Function-graph tracing: ftrace=function_graph ftrace_graph_filter=sched_setaffinity,migration_cpu_stop
532*4882a593Smuzhiyun# Also --kconfig "CONFIG_FUNCTION_TRACER=y CONFIG_FUNCTION_GRAPH_TRACER=y"
533*4882a593Smuzhiyun# Control buffer size: --bootargs trace_buf_size=3k
534*4882a593Smuzhiyun# Get trace-buffer dumps on all oopses: --bootargs ftrace_dump_on_oops
535*4882a593Smuzhiyun# Ditto, but dump only the oopsing CPU: --bootargs ftrace_dump_on_oops=orig_cpu
536*4882a593Smuzhiyun# Heavy-handed way to also dump on warnings: --bootargs panic_on_warn
537