diff options
| author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-01-18 00:56:57 -0500 |
|---|---|---|
| committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-02-18 15:27:19 -0500 |
| commit | 78ad0693233080169e5a01811bd3fcb3966f2d3f (patch) | |
| tree | eac4d60edfeadd070c949fea9fabfc19e63672d2 /tools/testing | |
| parent | 53954671033dc878acbeef1ecf9ac653c7b1a58f (diff) | |
rcutorture: Add comments, especially on bin packing.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'tools/testing')
| -rw-r--r-- | tools/testing/selftests/rcutorture/bin/kvm.sh | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh index 18649b87ea6c..7ef3b245c778 100644 --- a/tools/testing/selftests/rcutorture/bin/kvm.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm.sh | |||
| @@ -188,6 +188,7 @@ fi | |||
| 188 | mkdir $resdir/$ds | 188 | mkdir $resdir/$ds |
| 189 | if test "$dryrun" = "" | 189 | if test "$dryrun" = "" |
| 190 | then | 190 | then |
| 191 | # Be noisy only if running the script. | ||
| 191 | echo Results directory: $resdir/$ds | 192 | echo Results directory: $resdir/$ds |
| 192 | echo $scriptname $args | 193 | echo $scriptname $args |
| 193 | fi | 194 | fi |
| @@ -201,6 +202,7 @@ then | |||
| 201 | git rev-parse HEAD >> $resdir/$ds/testid.txt | 202 | git rev-parse HEAD >> $resdir/$ds/testid.txt |
| 202 | fi | 203 | fi |
| 203 | 204 | ||
| 205 | # Create a file of test-name/#cpus pairs, sorted by decreasing #cpus. | ||
| 204 | touch $T/cfgcpu | 206 | touch $T/cfgcpu |
| 205 | for CF in $configs | 207 | for CF in $configs |
| 206 | do | 208 | do |
| @@ -214,12 +216,14 @@ do | |||
| 214 | done | 216 | done |
| 215 | sort -k2nr $T/cfgcpu > $T/cfgcpu.sort | 217 | sort -k2nr $T/cfgcpu > $T/cfgcpu.sort |
| 216 | 218 | ||
| 219 | # Use a greedy bin-packing algorithm, sorting the list accordingly. | ||
| 217 | awk < $T/cfgcpu.sort > $T/cfgcpu.pack -v ncpus=$cpus ' | 220 | awk < $T/cfgcpu.sort > $T/cfgcpu.pack -v ncpus=$cpus ' |
| 218 | BEGIN { | 221 | BEGIN { |
| 219 | njobs = 0; | 222 | njobs = 0; |
| 220 | } | 223 | } |
| 221 | 224 | ||
| 222 | { | 225 | { |
| 226 | # Read file of tests and corresponding required numbers of CPUs. | ||
| 223 | cf[njobs] = $1; | 227 | cf[njobs] = $1; |
| 224 | cpus[njobs] = $2; | 228 | cpus[njobs] = $2; |
| 225 | njobs++; | 229 | njobs++; |
| @@ -229,26 +233,40 @@ END { | |||
| 229 | alldone = 0; | 233 | alldone = 0; |
| 230 | batch = 0; | 234 | batch = 0; |
| 231 | nc = -1; | 235 | nc = -1; |
| 236 | |||
| 237 | # Each pass through the following loop creates on test batch | ||
| 238 | # that can be executed concurrently given ncpus. Note that a | ||
| 239 | # given test that requires more than the available CPUs will run in | ||
| 240 | # their own batch. Such tests just have to make do with what | ||
| 241 | # is available. | ||
| 232 | while (nc != ncpus) { | 242 | while (nc != ncpus) { |
| 233 | batch++; | 243 | batch++; |
| 234 | nc = ncpus; | 244 | nc = ncpus; |
| 245 | |||
| 246 | # Each pass through the following loop considers one | ||
| 247 | # test for inclusion in the current batch. | ||
| 235 | for (i = 0; i < njobs; i++) { | 248 | for (i = 0; i < njobs; i++) { |
| 236 | if (done[i]) | 249 | if (done[i]) |
| 237 | continue; | 250 | continue; # Already part of a batch. |
| 238 | if (nc >= cpus[i] || nc == ncpus) { | 251 | if (nc >= cpus[i] || nc == ncpus) { |
| 252 | |||
| 253 | # This test fits into the current batch. | ||
| 239 | done[i] = batch; | 254 | done[i] = batch; |
| 240 | nc -= cpus[i]; | 255 | nc -= cpus[i]; |
| 241 | if (nc <= 0) | 256 | if (nc <= 0) |
| 242 | break; | 257 | break; # Too-big test in its own batch. |
| 243 | } | 258 | } |
| 244 | } | 259 | } |
| 245 | } | 260 | } |
| 261 | |||
| 262 | # Dump out the tests in batch order. | ||
| 246 | for (b = 1; b <= batch; b++) | 263 | for (b = 1; b <= batch; b++) |
| 247 | for (i = 0; i < njobs; i++) | 264 | for (i = 0; i < njobs; i++) |
| 248 | if (done[i] == b) | 265 | if (done[i] == b) |
| 249 | print cf[i], cpus[i]; | 266 | print cf[i], cpus[i]; |
| 250 | }' | 267 | }' |
| 251 | 268 | ||
| 269 | # Generate a script to execute the tests in appropriate batches. | ||
| 252 | awk < $T/cfgcpu.pack \ | 270 | awk < $T/cfgcpu.pack \ |
| 253 | -v CONFIGDIR="$CONFIGFRAG/$kversion/" \ | 271 | -v CONFIGDIR="$CONFIGFRAG/$kversion/" \ |
| 254 | -v KVM="$KVM" \ | 272 | -v KVM="$KVM" \ |
| @@ -267,6 +285,7 @@ awk < $T/cfgcpu.pack \ | |||
| 267 | i++; | 285 | i++; |
| 268 | } | 286 | } |
| 269 | 287 | ||
| 288 | # Dump out the scripting required to run one test batch. | ||
| 270 | function dump(first, pastlast) | 289 | function dump(first, pastlast) |
| 271 | { | 290 | { |
| 272 | print "echo ----start batch----" | 291 | print "echo ----start batch----" |
| @@ -313,23 +332,31 @@ END { | |||
| 313 | njobs = i; | 332 | njobs = i; |
| 314 | nc = ncpus; | 333 | nc = ncpus; |
| 315 | first = 0; | 334 | first = 0; |
| 335 | |||
| 336 | # Each pass through the following loop considers one test. | ||
| 316 | for (i = 0; i < njobs; i++) { | 337 | for (i = 0; i < njobs; i++) { |
| 317 | if (ncpus == 0) { | 338 | if (ncpus == 0) { |
| 339 | # Sequential test specified, each test its own batch. | ||
| 318 | dump(i, i + 1); | 340 | dump(i, i + 1); |
| 319 | first = i; | 341 | first = i; |
| 320 | } else if (nc < cpus[i] && i != 0) { | 342 | } else if (nc < cpus[i] && i != 0) { |
| 343 | # Out of CPUs, dump out a batch. | ||
| 321 | dump(first, i); | 344 | dump(first, i); |
| 322 | first = i; | 345 | first = i; |
| 323 | nc = ncpus; | 346 | nc = ncpus; |
| 324 | } | 347 | } |
| 348 | # Account for the CPUs needed by the current test. | ||
| 325 | nc -= cpus[i]; | 349 | nc -= cpus[i]; |
| 326 | } | 350 | } |
| 351 | # Dump the last batch. | ||
| 327 | if (ncpus != 0) | 352 | if (ncpus != 0) |
| 328 | dump(first, i); | 353 | dump(first, i); |
| 329 | }' > $T/script | 354 | }' > $T/script |
| 330 | 355 | ||
| 331 | if test "$dryrun" = script | 356 | if test "$dryrun" = script |
| 332 | then | 357 | then |
| 358 | # Dump out the script, but define the environment variables that | ||
| 359 | # it needs to run standalone. | ||
| 333 | echo CONFIGFRAG="$CONFIGFRAG; export CONFIGFRAG" | 360 | echo CONFIGFRAG="$CONFIGFRAG; export CONFIGFRAG" |
| 334 | echo KVM="$KVM; export KVM" | 361 | echo KVM="$KVM; export KVM" |
| 335 | echo KVPATH="$KVPATH; export KVPATH" | 362 | echo KVPATH="$KVPATH; export KVPATH" |
| @@ -344,10 +371,12 @@ then | |||
| 344 | exit 0 | 371 | exit 0 |
| 345 | elif test "$dryrun" = sched | 372 | elif test "$dryrun" = sched |
| 346 | then | 373 | then |
| 374 | # Extract the test run schedule from the script. | ||
| 347 | egrep 'start batch|Starting build\.' $T/script | | 375 | egrep 'start batch|Starting build\.' $T/script | |
| 348 | sed -e 's/:.*$//' -e 's/^echo //' | 376 | sed -e 's/:.*$//' -e 's/^echo //' |
| 349 | exit 0 | 377 | exit 0 |
| 350 | else | 378 | else |
| 379 | # Not a dryru, so run the script. | ||
| 351 | sh $T/script | 380 | sh $T/script |
| 352 | fi | 381 | fi |
| 353 | 382 | ||
