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