diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-02-26 09:38:59 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-02-26 09:38:59 -0500 |
commit | f5604f67fe8cbd6f2088b20b9463f721aa613d4b (patch) | |
tree | 27b16f4c8415d60c796c24472c29968bc8d39b04 | |
parent | 322efba5b6442f331ac8aa24e92a817d804cc938 (diff) | |
parent | 73fa867e2c705cf5cf0a38df8618fa20eee3d75a (diff) |
Merge branch 'torture.2014.02.23a' into HEAD
torture.2014.02.23a: locktorture addition and rcutorture changes
-rw-r--r-- | include/linux/torture.h | 100 | ||||
-rw-r--r-- | kernel/Makefile | 1 | ||||
-rw-r--r-- | kernel/locking/Makefile | 1 | ||||
-rw-r--r-- | kernel/locking/locktorture.c | 452 | ||||
-rw-r--r-- | kernel/rcu/Makefile | 2 | ||||
-rw-r--r-- | kernel/rcu/rcutorture.c (renamed from kernel/rcu/torture.c) | 992 | ||||
-rw-r--r-- | kernel/torture.c | 719 | ||||
-rw-r--r-- | lib/Kconfig.debug | 20 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/bin/functions.sh | 1 | ||||
-rwxr-xr-x | tools/testing/selftests/rcutorture/bin/kvm-recheck-lock.sh | 51 | ||||
-rwxr-xr-x | tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh | 51 | ||||
-rwxr-xr-x | tools/testing/selftests/rcutorture/bin/kvm-recheck.sh | 13 | ||||
-rwxr-xr-x | tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh (renamed from tools/testing/selftests/rcutorture/bin/kvm-test-1-rcu.sh) | 53 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/bin/kvm.sh | 276 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/lock/BUSTED | 6 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/lock/BUSTED.boot | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/lock/CFLIST | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/lock/CFcommon | 2 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/lock/LOCK01 | 6 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/lock/ver_functions.sh | 43 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/BUSTED | 7 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/BUSTED.boot | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/CFLIST (renamed from tools/testing/selftests/rcutorture/configs/CFLIST) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/CFcommon | 2 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/SRCU-N (renamed from tools/testing/selftests/rcutorture/configs/SRCU-N) | 3 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot (renamed from tools/testing/selftests/rcutorture/configs/SRCU-N.boot) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/SRCU-P (renamed from tools/testing/selftests/rcutorture/configs/SRCU-P) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot (renamed from tools/testing/selftests/rcutorture/configs/SRCU-P.boot) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TINY01 (renamed from tools/testing/selftests/rcutorture/configs/TINY01) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TINY02 (renamed from tools/testing/selftests/rcutorture/configs/TINY02) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE01 (renamed from tools/testing/selftests/rcutorture/configs/TREE01) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE01.boot (renamed from tools/testing/selftests/rcutorture/configs/TREE01.boot) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE02 (renamed from tools/testing/selftests/rcutorture/configs/TREE02) | 3 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE03 (renamed from tools/testing/selftests/rcutorture/configs/TREE03) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE04 (renamed from tools/testing/selftests/rcutorture/configs/TREE04) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE04.boot (renamed from tools/testing/selftests/rcutorture/configs/TREE04.boot) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE05 (renamed from tools/testing/selftests/rcutorture/configs/TREE05) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE05.boot (renamed from tools/testing/selftests/rcutorture/configs/TREE05.boot) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE06 (renamed from tools/testing/selftests/rcutorture/configs/TREE06) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE07 (renamed from tools/testing/selftests/rcutorture/configs/TREE07) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE08 (renamed from tools/testing/selftests/rcutorture/configs/TREE08) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE08-T (renamed from tools/testing/selftests/rcutorture/configs/TREE08-T) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/TREE09 (renamed from tools/testing/selftests/rcutorture/configs/TREE09) | 1 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/CFLIST (renamed from tools/testing/selftests/rcutorture/configs/v0.0/CFLIST) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/N1-S-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v0.0/N1-S-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/N2-2-t-nh-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v0.0/N2-2-t-nh-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/N3-3-T-nh-SD-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v0.0/N3-3-T-nh-SD-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/N4-A-t-NH-sd-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v0.0/N4-A-t-NH-sd-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/N5-U-T-NH-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v0.0/N5-U-T-NH-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/NT1-nh (renamed from tools/testing/selftests/rcutorture/configs/v0.0/NT1-nh) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/NT3-NH (renamed from tools/testing/selftests/rcutorture/configs/v0.0/NT3-NH) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/P1-S-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v0.0/P1-S-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/P2-2-t-nh-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v0.0/P2-2-t-nh-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/P3-3-T-nh-SD-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v0.0/P3-3-T-nh-SD-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/P4-A-t-NH-sd-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v0.0/P4-A-t-NH-sd-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/P5-U-T-NH-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v0.0/P5-U-T-NH-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/PT1-nh (renamed from tools/testing/selftests/rcutorture/configs/v0.0/PT1-nh) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/PT2-NH (renamed from tools/testing/selftests/rcutorture/configs/v0.0/PT2-NH) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v0.0/ver_functions.sh (renamed from tools/testing/selftests/rcutorture/configs/v0.0/ver_functions.sh) | 22 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/CFLIST (renamed from tools/testing/selftests/rcutorture/configs/v3.12/CFLIST) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/N1-S-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.12/N1-S-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/N2-2-t-nh-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.12/N2-2-t-nh-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/N3-3-T-nh-SD-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.12/N3-3-T-nh-SD-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/N4-A-t-NH-sd-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.12/N4-A-t-NH-sd-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/N5-U-T-NH-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.12/N5-U-T-NH-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/N6---t-nh-SD-smp-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.12/N6---t-nh-SD-smp-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/N7-4-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.12/N7-4-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/N8-2-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.12/N8-2-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/NT1-nh (renamed from tools/testing/selftests/rcutorture/configs/v3.12/NT1-nh) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/NT3-NH (renamed from tools/testing/selftests/rcutorture/configs/v3.12/NT3-NH) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P1-S-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P1-S-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P2-2-t-nh-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P2-2-t-nh-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P3-3-T-nh-SD-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P3-3-T-nh-SD-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P4-A-t-NH-sd-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P4-A-t-NH-sd-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P5-U-T-NH-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P5-U-T-NH-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P6---t-nh-SD-smp-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P6---t-nh-SD-smp-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-HP-all (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-HP-all) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-HP-none (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-HP-none) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/PT1-nh (renamed from tools/testing/selftests/rcutorture/configs/v3.12/PT1-nh) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.12/PT2-NH (renamed from tools/testing/selftests/rcutorture/configs/v3.12/PT2-NH) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/CFLIST (renamed from tools/testing/selftests/rcutorture/configs/v3.3/CFLIST) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/N1-S-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.3/N1-S-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/N2-2-t-nh-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.3/N2-2-t-nh-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/N3-3-T-nh-SD-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.3/N3-3-T-nh-SD-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/N4-A-t-NH-sd-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.3/N4-A-t-NH-sd-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/N5-U-T-NH-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.3/N5-U-T-NH-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/NT1-nh (renamed from tools/testing/selftests/rcutorture/configs/v3.3/NT1-nh) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/NT3-NH (renamed from tools/testing/selftests/rcutorture/configs/v3.3/NT3-NH) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/P1-S-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.3/P1-S-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/P2-2-t-nh-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.3/P2-2-t-nh-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/P3-3-T-nh-SD-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.3/P3-3-T-nh-SD-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/P4-A-t-NH-sd-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.3/P4-A-t-NH-sd-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/P5-U-T-NH-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.3/P5-U-T-NH-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/PT1-nh (renamed from tools/testing/selftests/rcutorture/configs/v3.3/PT1-nh) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/PT2-NH (renamed from tools/testing/selftests/rcutorture/configs/v3.3/PT2-NH) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.3/ver_functions.sh (renamed from tools/testing/selftests/rcutorture/configs/ver_functions.sh) | 28 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/CFLIST (renamed from tools/testing/selftests/rcutorture/configs/v3.5/CFLIST) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/N1-S-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.5/N1-S-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/N2-2-t-nh-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.5/N2-2-t-nh-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/N3-3-T-nh-SD-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.5/N3-3-T-nh-SD-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/N4-A-t-NH-sd-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.5/N4-A-t-NH-sd-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/N5-U-T-NH-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.5/N5-U-T-NH-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/NT1-nh (renamed from tools/testing/selftests/rcutorture/configs/v3.5/NT1-nh) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/NT3-NH (renamed from tools/testing/selftests/rcutorture/configs/v3.5/NT3-NH) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/P1-S-T-NH-SD-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.5/P1-S-T-NH-SD-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/P2-2-t-nh-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.5/P2-2-t-nh-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/P3-3-T-nh-SD-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.5/P3-3-T-nh-SD-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/P4-A-t-NH-sd-SMP-HP (renamed from tools/testing/selftests/rcutorture/configs/v3.5/P4-A-t-NH-sd-SMP-HP) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/P5-U-T-NH-sd-SMP-hp (renamed from tools/testing/selftests/rcutorture/configs/v3.5/P5-U-T-NH-sd-SMP-hp) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/PT1-nh (renamed from tools/testing/selftests/rcutorture/configs/v3.5/PT1-nh) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/PT2-NH (renamed from tools/testing/selftests/rcutorture/configs/v3.5/PT2-NH) | 0 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/v3.5/ver_functions.sh (renamed from tools/testing/selftests/rcutorture/configs/v3.5/ver_functions.sh) | 23 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh (renamed from tools/testing/selftests/rcutorture/configs/v3.3/ver_functions.sh) | 26 | ||||
-rw-r--r-- | tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt (renamed from tools/testing/selftests/rcutorture/doc/TREE_RCU-Kconfig.txt) | 0 |
116 files changed, 2023 insertions, 895 deletions
diff --git a/include/linux/torture.h b/include/linux/torture.h new file mode 100644 index 000000000000..b2e2b468e511 --- /dev/null +++ b/include/linux/torture.h | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * Common functions for in-kernel torture tests. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, you can access it online at | ||
16 | * http://www.gnu.org/licenses/gpl-2.0.html. | ||
17 | * | ||
18 | * Copyright IBM Corporation, 2014 | ||
19 | * | ||
20 | * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | ||
21 | */ | ||
22 | |||
23 | #ifndef __LINUX_TORTURE_H | ||
24 | #define __LINUX_TORTURE_H | ||
25 | |||
26 | #include <linux/types.h> | ||
27 | #include <linux/cache.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/threads.h> | ||
30 | #include <linux/cpumask.h> | ||
31 | #include <linux/seqlock.h> | ||
32 | #include <linux/lockdep.h> | ||
33 | #include <linux/completion.h> | ||
34 | #include <linux/debugobjects.h> | ||
35 | #include <linux/bug.h> | ||
36 | #include <linux/compiler.h> | ||
37 | |||
38 | /* Definitions for a non-string torture-test module parameter. */ | ||
39 | #define torture_param(type, name, init, msg) \ | ||
40 | static type name = init; \ | ||
41 | module_param(name, type, 0444); \ | ||
42 | MODULE_PARM_DESC(name, msg); | ||
43 | |||
44 | #define TORTURE_FLAG "-torture:" | ||
45 | #define TOROUT_STRING(s) \ | ||
46 | pr_alert("%s" TORTURE_FLAG s "\n", torture_type) | ||
47 | #define VERBOSE_TOROUT_STRING(s) \ | ||
48 | do { if (verbose) pr_alert("%s" TORTURE_FLAG " %s\n", torture_type, s); } while (0) | ||
49 | #define VERBOSE_TOROUT_ERRSTRING(s) \ | ||
50 | do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! %s\n", torture_type, s); } while (0) | ||
51 | |||
52 | /* Definitions for a non-string torture-test module parameter. */ | ||
53 | #define torture_parm(type, name, init, msg) \ | ||
54 | static type name = init; \ | ||
55 | module_param(name, type, 0444); \ | ||
56 | MODULE_PARM_DESC(name, msg); | ||
57 | |||
58 | /* Definitions for online/offline exerciser. */ | ||
59 | int torture_onoff_init(long ooholdoff, long oointerval); | ||
60 | char *torture_onoff_stats(char *page); | ||
61 | bool torture_onoff_failures(void); | ||
62 | |||
63 | /* Low-rider random number generator. */ | ||
64 | struct torture_random_state { | ||
65 | unsigned long trs_state; | ||
66 | long trs_count; | ||
67 | }; | ||
68 | #define DEFINE_TORTURE_RANDOM(name) struct torture_random_state name = { 0, 0 } | ||
69 | unsigned long torture_random(struct torture_random_state *trsp); | ||
70 | |||
71 | /* Task shuffler, which causes CPUs to occasionally go idle. */ | ||
72 | void torture_shuffle_task_register(struct task_struct *tp); | ||
73 | int torture_shuffle_init(long shuffint); | ||
74 | |||
75 | /* Test auto-shutdown handling. */ | ||
76 | void torture_shutdown_absorb(const char *title); | ||
77 | int torture_shutdown_init(int ssecs, void (*cleanup)(void)); | ||
78 | |||
79 | /* Task stuttering, which forces load/no-load transitions. */ | ||
80 | void stutter_wait(const char *title); | ||
81 | int torture_stutter_init(int s); | ||
82 | |||
83 | /* Initialization and cleanup. */ | ||
84 | void torture_init_begin(char *ttype, bool v, int *runnable); | ||
85 | void torture_init_end(void); | ||
86 | bool torture_cleanup(void); | ||
87 | bool torture_must_stop(void); | ||
88 | bool torture_must_stop_irq(void); | ||
89 | void torture_kthread_stopping(char *title); | ||
90 | int _torture_create_kthread(int (*fn)(void *arg), void *arg, char *s, char *m, | ||
91 | char *f, struct task_struct **tp); | ||
92 | void _torture_stop_kthread(char *m, struct task_struct **tp); | ||
93 | |||
94 | #define torture_create_kthread(n, arg, tp) \ | ||
95 | _torture_create_kthread(n, (arg), #n, "Creating " #n " task", \ | ||
96 | "Failed to create " #n, &(tp)) | ||
97 | #define torture_stop_kthread(n, tp) \ | ||
98 | _torture_stop_kthread("Stopping " #n " task", &(tp)) | ||
99 | |||
100 | #endif /* __LINUX_TORTURE_H */ | ||
diff --git a/kernel/Makefile b/kernel/Makefile index bc010ee272b6..5c0e7666811d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -93,6 +93,7 @@ obj-$(CONFIG_PADATA) += padata.o | |||
93 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | 93 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
94 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o | 94 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o |
95 | obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o | 95 | obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o |
96 | obj-$(CONFIG_TORTURE_TEST) += torture.o | ||
96 | 97 | ||
97 | $(obj)/configs.o: $(obj)/config_data.h | 98 | $(obj)/configs.o: $(obj)/config_data.h |
98 | 99 | ||
diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile index baab8e5e7f66..a28ea6d9e6e8 100644 --- a/kernel/locking/Makefile +++ b/kernel/locking/Makefile | |||
@@ -23,3 +23,4 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o | |||
23 | obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o | 23 | obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o |
24 | obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o | 24 | obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o |
25 | obj-$(CONFIG_PERCPU_RWSEM) += percpu-rwsem.o | 25 | obj-$(CONFIG_PERCPU_RWSEM) += percpu-rwsem.o |
26 | obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o | ||
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c new file mode 100644 index 000000000000..f26b1a18e34e --- /dev/null +++ b/kernel/locking/locktorture.c | |||
@@ -0,0 +1,452 @@ | |||
1 | /* | ||
2 | * Module-based torture test facility for locking | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, you can access it online at | ||
16 | * http://www.gnu.org/licenses/gpl-2.0.html. | ||
17 | * | ||
18 | * Copyright (C) IBM Corporation, 2014 | ||
19 | * | ||
20 | * Author: Paul E. McKenney <paulmck@us.ibm.com> | ||
21 | * Based on kernel/rcu/torture.c. | ||
22 | */ | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/kthread.h> | ||
28 | #include <linux/err.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/smp.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/sched.h> | ||
33 | #include <linux/atomic.h> | ||
34 | #include <linux/bitops.h> | ||
35 | #include <linux/completion.h> | ||
36 | #include <linux/moduleparam.h> | ||
37 | #include <linux/percpu.h> | ||
38 | #include <linux/notifier.h> | ||
39 | #include <linux/reboot.h> | ||
40 | #include <linux/freezer.h> | ||
41 | #include <linux/cpu.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/stat.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <linux/trace_clock.h> | ||
46 | #include <asm/byteorder.h> | ||
47 | #include <linux/torture.h> | ||
48 | |||
49 | MODULE_LICENSE("GPL"); | ||
50 | MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com>"); | ||
51 | |||
52 | torture_param(int, nwriters_stress, -1, | ||
53 | "Number of write-locking stress-test threads"); | ||
54 | torture_param(int, onoff_holdoff, 0, "Time after boot before CPU hotplugs (s)"); | ||
55 | torture_param(int, onoff_interval, 0, | ||
56 | "Time between CPU hotplugs (s), 0=disable"); | ||
57 | torture_param(int, shuffle_interval, 3, | ||
58 | "Number of jiffies between shuffles, 0=disable"); | ||
59 | torture_param(int, shutdown_secs, 0, "Shutdown time (j), <= zero to disable."); | ||
60 | torture_param(int, stat_interval, 60, | ||
61 | "Number of seconds between stats printk()s"); | ||
62 | torture_param(int, stutter, 5, "Number of jiffies to run/halt test, 0=disable"); | ||
63 | torture_param(bool, verbose, true, | ||
64 | "Enable verbose debugging printk()s"); | ||
65 | |||
66 | static char *torture_type = "spin_lock"; | ||
67 | module_param(torture_type, charp, 0444); | ||
68 | MODULE_PARM_DESC(torture_type, | ||
69 | "Type of lock to torture (spin_lock, spin_lock_irq, ...)"); | ||
70 | |||
71 | static atomic_t n_lock_torture_errors; | ||
72 | |||
73 | static struct task_struct *stats_task; | ||
74 | static struct task_struct **writer_tasks; | ||
75 | |||
76 | static int nrealwriters_stress; | ||
77 | static bool lock_is_write_held; | ||
78 | |||
79 | struct lock_writer_stress_stats { | ||
80 | long n_write_lock_fail; | ||
81 | long n_write_lock_acquired; | ||
82 | }; | ||
83 | static struct lock_writer_stress_stats *lwsa; | ||
84 | |||
85 | #if defined(MODULE) || defined(CONFIG_LOCK_TORTURE_TEST_RUNNABLE) | ||
86 | #define LOCKTORTURE_RUNNABLE_INIT 1 | ||
87 | #else | ||
88 | #define LOCKTORTURE_RUNNABLE_INIT 0 | ||
89 | #endif | ||
90 | int locktorture_runnable = LOCKTORTURE_RUNNABLE_INIT; | ||
91 | module_param(locktorture_runnable, int, 0444); | ||
92 | MODULE_PARM_DESC(locktorture_runnable, "Start locktorture at boot"); | ||
93 | |||
94 | /* Forward reference. */ | ||
95 | static void lock_torture_cleanup(void); | ||
96 | |||
97 | /* | ||
98 | * Operations vector for selecting different types of tests. | ||
99 | */ | ||
100 | struct lock_torture_ops { | ||
101 | void (*init)(void); | ||
102 | int (*writelock)(void); | ||
103 | void (*write_delay)(struct torture_random_state *trsp); | ||
104 | void (*writeunlock)(void); | ||
105 | unsigned long flags; | ||
106 | const char *name; | ||
107 | }; | ||
108 | |||
109 | static struct lock_torture_ops *cur_ops; | ||
110 | |||
111 | /* | ||
112 | * Definitions for lock torture testing. | ||
113 | */ | ||
114 | |||
115 | static int torture_lock_busted_write_lock(void) | ||
116 | { | ||
117 | return 0; /* BUGGY, do not use in real life!!! */ | ||
118 | } | ||
119 | |||
120 | static void torture_lock_busted_write_delay(struct torture_random_state *trsp) | ||
121 | { | ||
122 | const unsigned long longdelay_us = 100; | ||
123 | |||
124 | /* We want a long delay occasionally to force massive contention. */ | ||
125 | if (!(torture_random(trsp) % | ||
126 | (nrealwriters_stress * 2000 * longdelay_us))) | ||
127 | mdelay(longdelay_us); | ||
128 | #ifdef CONFIG_PREEMPT | ||
129 | if (!(torture_random(trsp) % (nrealwriters_stress * 20000))) | ||
130 | preempt_schedule(); /* Allow test to be preempted. */ | ||
131 | #endif | ||
132 | } | ||
133 | |||
134 | static void torture_lock_busted_write_unlock(void) | ||
135 | { | ||
136 | /* BUGGY, do not use in real life!!! */ | ||
137 | } | ||
138 | |||
139 | static struct lock_torture_ops lock_busted_ops = { | ||
140 | .writelock = torture_lock_busted_write_lock, | ||
141 | .write_delay = torture_lock_busted_write_delay, | ||
142 | .writeunlock = torture_lock_busted_write_unlock, | ||
143 | .name = "lock_busted" | ||
144 | }; | ||
145 | |||
146 | static DEFINE_SPINLOCK(torture_spinlock); | ||
147 | |||
148 | static int torture_spin_lock_write_lock(void) __acquires(torture_spinlock) | ||
149 | { | ||
150 | spin_lock(&torture_spinlock); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static void torture_spin_lock_write_delay(struct torture_random_state *trsp) | ||
155 | { | ||
156 | const unsigned long shortdelay_us = 2; | ||
157 | const unsigned long longdelay_us = 100; | ||
158 | |||
159 | /* We want a short delay mostly to emulate likely code, and | ||
160 | * we want a long delay occasionally to force massive contention. | ||
161 | */ | ||
162 | if (!(torture_random(trsp) % | ||
163 | (nrealwriters_stress * 2000 * longdelay_us))) | ||
164 | mdelay(longdelay_us); | ||
165 | if (!(torture_random(trsp) % | ||
166 | (nrealwriters_stress * 2 * shortdelay_us))) | ||
167 | udelay(shortdelay_us); | ||
168 | #ifdef CONFIG_PREEMPT | ||
169 | if (!(torture_random(trsp) % (nrealwriters_stress * 20000))) | ||
170 | preempt_schedule(); /* Allow test to be preempted. */ | ||
171 | #endif | ||
172 | } | ||
173 | |||
174 | static void torture_spin_lock_write_unlock(void) __releases(torture_spinlock) | ||
175 | { | ||
176 | spin_unlock(&torture_spinlock); | ||
177 | } | ||
178 | |||
179 | static struct lock_torture_ops spin_lock_ops = { | ||
180 | .writelock = torture_spin_lock_write_lock, | ||
181 | .write_delay = torture_spin_lock_write_delay, | ||
182 | .writeunlock = torture_spin_lock_write_unlock, | ||
183 | .name = "spin_lock" | ||
184 | }; | ||
185 | |||
186 | static int torture_spin_lock_write_lock_irq(void) | ||
187 | __acquires(torture_spinlock_irq) | ||
188 | { | ||
189 | unsigned long flags; | ||
190 | |||
191 | spin_lock_irqsave(&torture_spinlock, flags); | ||
192 | cur_ops->flags = flags; | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static void torture_lock_spin_write_unlock_irq(void) | ||
197 | __releases(torture_spinlock) | ||
198 | { | ||
199 | spin_unlock_irqrestore(&torture_spinlock, cur_ops->flags); | ||
200 | } | ||
201 | |||
202 | static struct lock_torture_ops spin_lock_irq_ops = { | ||
203 | .writelock = torture_spin_lock_write_lock_irq, | ||
204 | .write_delay = torture_spin_lock_write_delay, | ||
205 | .writeunlock = torture_lock_spin_write_unlock_irq, | ||
206 | .name = "spin_lock_irq" | ||
207 | }; | ||
208 | |||
209 | /* | ||
210 | * Lock torture writer kthread. Repeatedly acquires and releases | ||
211 | * the lock, checking for duplicate acquisitions. | ||
212 | */ | ||
213 | static int lock_torture_writer(void *arg) | ||
214 | { | ||
215 | struct lock_writer_stress_stats *lwsp = arg; | ||
216 | static DEFINE_TORTURE_RANDOM(rand); | ||
217 | |||
218 | VERBOSE_TOROUT_STRING("lock_torture_writer task started"); | ||
219 | set_user_nice(current, 19); | ||
220 | |||
221 | do { | ||
222 | schedule_timeout_uninterruptible(1); | ||
223 | cur_ops->writelock(); | ||
224 | if (WARN_ON_ONCE(lock_is_write_held)) | ||
225 | lwsp->n_write_lock_fail++; | ||
226 | lock_is_write_held = 1; | ||
227 | lwsp->n_write_lock_acquired++; | ||
228 | cur_ops->write_delay(&rand); | ||
229 | lock_is_write_held = 0; | ||
230 | cur_ops->writeunlock(); | ||
231 | stutter_wait("lock_torture_writer"); | ||
232 | } while (!torture_must_stop()); | ||
233 | torture_kthread_stopping("lock_torture_writer"); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | /* | ||
238 | * Create an lock-torture-statistics message in the specified buffer. | ||
239 | */ | ||
240 | static void lock_torture_printk(char *page) | ||
241 | { | ||
242 | bool fail = 0; | ||
243 | int i; | ||
244 | long max = 0; | ||
245 | long min = lwsa[0].n_write_lock_acquired; | ||
246 | long long sum = 0; | ||
247 | |||
248 | for (i = 0; i < nrealwriters_stress; i++) { | ||
249 | if (lwsa[i].n_write_lock_fail) | ||
250 | fail = true; | ||
251 | sum += lwsa[i].n_write_lock_acquired; | ||
252 | if (max < lwsa[i].n_write_lock_fail) | ||
253 | max = lwsa[i].n_write_lock_fail; | ||
254 | if (min > lwsa[i].n_write_lock_fail) | ||
255 | min = lwsa[i].n_write_lock_fail; | ||
256 | } | ||
257 | page += sprintf(page, "%s%s ", torture_type, TORTURE_FLAG); | ||
258 | page += sprintf(page, | ||
259 | "Writes: Total: %lld Max/Min: %ld/%ld %s Fail: %d %s\n", | ||
260 | sum, max, min, max / 2 > min ? "???" : "", | ||
261 | fail, fail ? "!!!" : ""); | ||
262 | if (fail) | ||
263 | atomic_inc(&n_lock_torture_errors); | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * Print torture statistics. Caller must ensure that there is only one | ||
268 | * call to this function at a given time!!! This is normally accomplished | ||
269 | * by relying on the module system to only have one copy of the module | ||
270 | * loaded, and then by giving the lock_torture_stats kthread full control | ||
271 | * (or the init/cleanup functions when lock_torture_stats thread is not | ||
272 | * running). | ||
273 | */ | ||
274 | static void lock_torture_stats_print(void) | ||
275 | { | ||
276 | int size = nrealwriters_stress * 200 + 8192; | ||
277 | char *buf; | ||
278 | |||
279 | buf = kmalloc(size, GFP_KERNEL); | ||
280 | if (!buf) { | ||
281 | pr_err("lock_torture_stats_print: Out of memory, need: %d", | ||
282 | size); | ||
283 | return; | ||
284 | } | ||
285 | lock_torture_printk(buf); | ||
286 | pr_alert("%s", buf); | ||
287 | kfree(buf); | ||
288 | } | ||
289 | |||
290 | /* | ||
291 | * Periodically prints torture statistics, if periodic statistics printing | ||
292 | * was specified via the stat_interval module parameter. | ||
293 | * | ||
294 | * No need to worry about fullstop here, since this one doesn't reference | ||
295 | * volatile state or register callbacks. | ||
296 | */ | ||
297 | static int lock_torture_stats(void *arg) | ||
298 | { | ||
299 | VERBOSE_TOROUT_STRING("lock_torture_stats task started"); | ||
300 | do { | ||
301 | schedule_timeout_interruptible(stat_interval * HZ); | ||
302 | lock_torture_stats_print(); | ||
303 | torture_shutdown_absorb("lock_torture_stats"); | ||
304 | } while (!torture_must_stop()); | ||
305 | torture_kthread_stopping("lock_torture_stats"); | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static inline void | ||
310 | lock_torture_print_module_parms(struct lock_torture_ops *cur_ops, | ||
311 | const char *tag) | ||
312 | { | ||
313 | pr_alert("%s" TORTURE_FLAG | ||
314 | "--- %s: nwriters_stress=%d stat_interval=%d verbose=%d shuffle_interval=%d stutter=%d shutdown_secs=%d onoff_interval=%d onoff_holdoff=%d\n", | ||
315 | torture_type, tag, nrealwriters_stress, stat_interval, verbose, | ||
316 | shuffle_interval, stutter, shutdown_secs, | ||
317 | onoff_interval, onoff_holdoff); | ||
318 | } | ||
319 | |||
320 | static void lock_torture_cleanup(void) | ||
321 | { | ||
322 | int i; | ||
323 | |||
324 | if (torture_cleanup()) | ||
325 | return; | ||
326 | |||
327 | if (writer_tasks) { | ||
328 | for (i = 0; i < nrealwriters_stress; i++) | ||
329 | torture_stop_kthread(lock_torture_writer, | ||
330 | writer_tasks[i]); | ||
331 | kfree(writer_tasks); | ||
332 | writer_tasks = NULL; | ||
333 | } | ||
334 | |||
335 | torture_stop_kthread(lock_torture_stats, stats_task); | ||
336 | lock_torture_stats_print(); /* -After- the stats thread is stopped! */ | ||
337 | |||
338 | if (atomic_read(&n_lock_torture_errors)) | ||
339 | lock_torture_print_module_parms(cur_ops, | ||
340 | "End of test: FAILURE"); | ||
341 | else if (torture_onoff_failures()) | ||
342 | lock_torture_print_module_parms(cur_ops, | ||
343 | "End of test: LOCK_HOTPLUG"); | ||
344 | else | ||
345 | lock_torture_print_module_parms(cur_ops, | ||
346 | "End of test: SUCCESS"); | ||
347 | } | ||
348 | |||
349 | static int __init lock_torture_init(void) | ||
350 | { | ||
351 | int i; | ||
352 | int firsterr = 0; | ||
353 | static struct lock_torture_ops *torture_ops[] = { | ||
354 | &lock_busted_ops, &spin_lock_ops, &spin_lock_irq_ops, | ||
355 | }; | ||
356 | |||
357 | torture_init_begin(torture_type, verbose, &locktorture_runnable); | ||
358 | |||
359 | /* Process args and tell the world that the torturer is on the job. */ | ||
360 | for (i = 0; i < ARRAY_SIZE(torture_ops); i++) { | ||
361 | cur_ops = torture_ops[i]; | ||
362 | if (strcmp(torture_type, cur_ops->name) == 0) | ||
363 | break; | ||
364 | } | ||
365 | if (i == ARRAY_SIZE(torture_ops)) { | ||
366 | pr_alert("lock-torture: invalid torture type: \"%s\"\n", | ||
367 | torture_type); | ||
368 | pr_alert("lock-torture types:"); | ||
369 | for (i = 0; i < ARRAY_SIZE(torture_ops); i++) | ||
370 | pr_alert(" %s", torture_ops[i]->name); | ||
371 | pr_alert("\n"); | ||
372 | torture_init_end(); | ||
373 | return -EINVAL; | ||
374 | } | ||
375 | if (cur_ops->init) | ||
376 | cur_ops->init(); /* no "goto unwind" prior to this point!!! */ | ||
377 | |||
378 | if (nwriters_stress >= 0) | ||
379 | nrealwriters_stress = nwriters_stress; | ||
380 | else | ||
381 | nrealwriters_stress = 2 * num_online_cpus(); | ||
382 | lock_torture_print_module_parms(cur_ops, "Start of test"); | ||
383 | |||
384 | /* Initialize the statistics so that each run gets its own numbers. */ | ||
385 | |||
386 | lock_is_write_held = 0; | ||
387 | lwsa = kmalloc(sizeof(*lwsa) * nrealwriters_stress, GFP_KERNEL); | ||
388 | if (lwsa == NULL) { | ||
389 | VERBOSE_TOROUT_STRING("lwsa: Out of memory"); | ||
390 | firsterr = -ENOMEM; | ||
391 | goto unwind; | ||
392 | } | ||
393 | for (i = 0; i < nrealwriters_stress; i++) { | ||
394 | lwsa[i].n_write_lock_fail = 0; | ||
395 | lwsa[i].n_write_lock_acquired = 0; | ||
396 | } | ||
397 | |||
398 | /* Start up the kthreads. */ | ||
399 | |||
400 | if (onoff_interval > 0) { | ||
401 | firsterr = torture_onoff_init(onoff_holdoff * HZ, | ||
402 | onoff_interval * HZ); | ||
403 | if (firsterr) | ||
404 | goto unwind; | ||
405 | } | ||
406 | if (shuffle_interval > 0) { | ||
407 | firsterr = torture_shuffle_init(shuffle_interval); | ||
408 | if (firsterr) | ||
409 | goto unwind; | ||
410 | } | ||
411 | if (shutdown_secs > 0) { | ||
412 | firsterr = torture_shutdown_init(shutdown_secs, | ||
413 | lock_torture_cleanup); | ||
414 | if (firsterr) | ||
415 | goto unwind; | ||
416 | } | ||
417 | if (stutter > 0) { | ||
418 | firsterr = torture_stutter_init(stutter); | ||
419 | if (firsterr) | ||
420 | goto unwind; | ||
421 | } | ||
422 | |||
423 | writer_tasks = kzalloc(nrealwriters_stress * sizeof(writer_tasks[0]), | ||
424 | GFP_KERNEL); | ||
425 | if (writer_tasks == NULL) { | ||
426 | VERBOSE_TOROUT_ERRSTRING("writer_tasks: Out of memory"); | ||
427 | firsterr = -ENOMEM; | ||
428 | goto unwind; | ||
429 | } | ||
430 | for (i = 0; i < nrealwriters_stress; i++) { | ||
431 | firsterr = torture_create_kthread(lock_torture_writer, &lwsa[i], | ||
432 | writer_tasks[i]); | ||
433 | if (firsterr) | ||
434 | goto unwind; | ||
435 | } | ||
436 | if (stat_interval > 0) { | ||
437 | firsterr = torture_create_kthread(lock_torture_stats, NULL, | ||
438 | stats_task); | ||
439 | if (firsterr) | ||
440 | goto unwind; | ||
441 | } | ||
442 | torture_init_end(); | ||
443 | return 0; | ||
444 | |||
445 | unwind: | ||
446 | torture_init_end(); | ||
447 | lock_torture_cleanup(); | ||
448 | return firsterr; | ||
449 | } | ||
450 | |||
451 | module_init(lock_torture_init); | ||
452 | module_exit(lock_torture_cleanup); | ||
diff --git a/kernel/rcu/Makefile b/kernel/rcu/Makefile index 01e9ec37a3e3..807ccfbf69b3 100644 --- a/kernel/rcu/Makefile +++ b/kernel/rcu/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | obj-y += update.o srcu.o | 1 | obj-y += update.o srcu.o |
2 | obj-$(CONFIG_RCU_TORTURE_TEST) += torture.o | 2 | obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o |
3 | obj-$(CONFIG_TREE_RCU) += tree.o | 3 | obj-$(CONFIG_TREE_RCU) += tree.o |
4 | obj-$(CONFIG_TREE_PREEMPT_RCU) += tree.o | 4 | obj-$(CONFIG_TREE_PREEMPT_RCU) += tree.o |
5 | obj-$(CONFIG_TREE_RCU_TRACE) += tree_trace.o | 5 | obj-$(CONFIG_TREE_RCU_TRACE) += tree_trace.o |
diff --git a/kernel/rcu/torture.c b/kernel/rcu/rcutorture.c index 022c5312b725..f59d48597dde 100644 --- a/kernel/rcu/torture.c +++ b/kernel/rcu/rcutorture.c | |||
@@ -48,110 +48,58 @@ | |||
48 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
49 | #include <linux/trace_clock.h> | 49 | #include <linux/trace_clock.h> |
50 | #include <asm/byteorder.h> | 50 | #include <asm/byteorder.h> |
51 | #include <linux/torture.h> | ||
51 | 52 | ||
52 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
53 | MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@freedesktop.org>"); | 54 | MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@freedesktop.org>"); |
54 | 55 | ||
55 | MODULE_ALIAS("rcutorture"); | 56 | |
56 | #ifdef MODULE_PARAM_PREFIX | 57 | torture_param(int, fqs_duration, 0, |
57 | #undef MODULE_PARAM_PREFIX | 58 | "Duration of fqs bursts (us), 0 to disable"); |
58 | #endif | 59 | torture_param(int, fqs_holdoff, 0, "Holdoff time within fqs bursts (us)"); |
59 | #define MODULE_PARAM_PREFIX "rcutorture." | 60 | torture_param(int, fqs_stutter, 3, "Wait time between fqs bursts (s)"); |
60 | 61 | torture_param(bool, gp_exp, false, "Use expedited GP wait primitives"); | |
61 | static int fqs_duration; | 62 | torture_param(bool, gp_normal, false, |
62 | module_param(fqs_duration, int, 0444); | 63 | "Use normal (non-expedited) GP wait primitives"); |
63 | MODULE_PARM_DESC(fqs_duration, "Duration of fqs bursts (us), 0 to disable"); | 64 | torture_param(int, irqreader, 1, "Allow RCU readers from irq handlers"); |
64 | static int fqs_holdoff; | 65 | torture_param(int, n_barrier_cbs, 0, |
65 | module_param(fqs_holdoff, int, 0444); | 66 | "# of callbacks/kthreads for barrier testing"); |
66 | MODULE_PARM_DESC(fqs_holdoff, "Holdoff time within fqs bursts (us)"); | 67 | torture_param(int, nfakewriters, 4, "Number of RCU fake writer threads"); |
67 | static int fqs_stutter = 3; | 68 | torture_param(int, nreaders, -1, "Number of RCU reader threads"); |
68 | module_param(fqs_stutter, int, 0444); | 69 | torture_param(int, object_debug, 0, |
69 | MODULE_PARM_DESC(fqs_stutter, "Wait time between fqs bursts (s)"); | 70 | "Enable debug-object double call_rcu() testing"); |
70 | static bool gp_exp; | 71 | torture_param(int, onoff_holdoff, 0, "Time after boot before CPU hotplugs (s)"); |
71 | module_param(gp_exp, bool, 0444); | 72 | torture_param(int, onoff_interval, 0, |
72 | MODULE_PARM_DESC(gp_exp, "Use expedited GP wait primitives"); | 73 | "Time between CPU hotplugs (s), 0=disable"); |
73 | static bool gp_normal; | 74 | torture_param(int, shuffle_interval, 3, "Number of seconds between shuffles"); |
74 | module_param(gp_normal, bool, 0444); | 75 | torture_param(int, shutdown_secs, 0, "Shutdown time (s), <= zero to disable."); |
75 | MODULE_PARM_DESC(gp_normal, "Use normal (non-expedited) GP wait primitives"); | 76 | torture_param(int, stall_cpu, 0, "Stall duration (s), zero to disable."); |
76 | static int irqreader = 1; | 77 | torture_param(int, stall_cpu_holdoff, 10, |
77 | module_param(irqreader, int, 0444); | 78 | "Time to wait before starting stall (s)."); |
78 | MODULE_PARM_DESC(irqreader, "Allow RCU readers from irq handlers"); | 79 | torture_param(int, stat_interval, 60, |
79 | static int n_barrier_cbs; | 80 | "Number of seconds between stats printk()s"); |
80 | module_param(n_barrier_cbs, int, 0444); | 81 | torture_param(int, stutter, 5, "Number of seconds to run/halt test"); |
81 | MODULE_PARM_DESC(n_barrier_cbs, "# of callbacks/kthreads for barrier testing"); | 82 | torture_param(int, test_boost, 1, "Test RCU prio boost: 0=no, 1=maybe, 2=yes."); |
82 | static int nfakewriters = 4; | 83 | torture_param(int, test_boost_duration, 4, |
83 | module_param(nfakewriters, int, 0444); | 84 | "Duration of each boost test, seconds."); |
84 | MODULE_PARM_DESC(nfakewriters, "Number of RCU fake writer threads"); | 85 | torture_param(int, test_boost_interval, 7, |
85 | static int nreaders = -1; | 86 | "Interval between boost tests, seconds."); |
86 | module_param(nreaders, int, 0444); | 87 | torture_param(bool, test_no_idle_hz, true, |
87 | MODULE_PARM_DESC(nreaders, "Number of RCU reader threads"); | 88 | "Test support for tickless idle CPUs"); |
88 | static int object_debug; | 89 | torture_param(bool, verbose, true, |
89 | module_param(object_debug, int, 0444); | 90 | "Enable verbose debugging printk()s"); |
90 | MODULE_PARM_DESC(object_debug, "Enable debug-object double call_rcu() testing"); | 91 | |
91 | static int onoff_holdoff; | ||
92 | module_param(onoff_holdoff, int, 0444); | ||
93 | MODULE_PARM_DESC(onoff_holdoff, "Time after boot before CPU hotplugs (s)"); | ||
94 | static int onoff_interval; | ||
95 | module_param(onoff_interval, int, 0444); | ||
96 | MODULE_PARM_DESC(onoff_interval, "Time between CPU hotplugs (s), 0=disable"); | ||
97 | static int shuffle_interval = 3; | ||
98 | module_param(shuffle_interval, int, 0444); | ||
99 | MODULE_PARM_DESC(shuffle_interval, "Number of seconds between shuffles"); | ||
100 | static int shutdown_secs; | ||
101 | module_param(shutdown_secs, int, 0444); | ||
102 | MODULE_PARM_DESC(shutdown_secs, "Shutdown time (s), <= zero to disable."); | ||
103 | static int stall_cpu; | ||
104 | module_param(stall_cpu, int, 0444); | ||
105 | MODULE_PARM_DESC(stall_cpu, "Stall duration (s), zero to disable."); | ||
106 | static int stall_cpu_holdoff = 10; | ||
107 | module_param(stall_cpu_holdoff, int, 0444); | ||
108 | MODULE_PARM_DESC(stall_cpu_holdoff, "Time to wait before starting stall (s)."); | ||
109 | static int stat_interval = 60; | ||
110 | module_param(stat_interval, int, 0644); | ||
111 | MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s"); | ||
112 | static int stutter = 5; | ||
113 | module_param(stutter, int, 0444); | ||
114 | MODULE_PARM_DESC(stutter, "Number of seconds to run/halt test"); | ||
115 | static int test_boost = 1; | ||
116 | module_param(test_boost, int, 0444); | ||
117 | MODULE_PARM_DESC(test_boost, "Test RCU prio boost: 0=no, 1=maybe, 2=yes."); | ||
118 | static int test_boost_duration = 4; | ||
119 | module_param(test_boost_duration, int, 0444); | ||
120 | MODULE_PARM_DESC(test_boost_duration, "Duration of each boost test, seconds."); | ||
121 | static int test_boost_interval = 7; | ||
122 | module_param(test_boost_interval, int, 0444); | ||
123 | MODULE_PARM_DESC(test_boost_interval, "Interval between boost tests, seconds."); | ||
124 | static bool test_no_idle_hz = true; | ||
125 | module_param(test_no_idle_hz, bool, 0444); | ||
126 | MODULE_PARM_DESC(test_no_idle_hz, "Test support for tickless idle CPUs"); | ||
127 | static char *torture_type = "rcu"; | 92 | static char *torture_type = "rcu"; |
128 | module_param(torture_type, charp, 0444); | 93 | module_param(torture_type, charp, 0444); |
129 | MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, ...)"); | 94 | MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, ...)"); |
130 | static bool verbose; | ||
131 | module_param(verbose, bool, 0444); | ||
132 | MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s"); | ||
133 | |||
134 | #define TORTURE_FLAG "-torture:" | ||
135 | #define PRINTK_STRING(s) \ | ||
136 | do { pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0) | ||
137 | #define VERBOSE_PRINTK_STRING(s) \ | ||
138 | do { if (verbose) pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0) | ||
139 | #define VERBOSE_PRINTK_ERRSTRING(s) \ | ||
140 | do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! " s "\n", torture_type); } while (0) | ||
141 | 95 | ||
142 | static int nrealreaders; | 96 | static int nrealreaders; |
143 | static struct task_struct *writer_task; | 97 | static struct task_struct *writer_task; |
144 | static struct task_struct **fakewriter_tasks; | 98 | static struct task_struct **fakewriter_tasks; |
145 | static struct task_struct **reader_tasks; | 99 | static struct task_struct **reader_tasks; |
146 | static struct task_struct *stats_task; | 100 | static struct task_struct *stats_task; |
147 | static struct task_struct *shuffler_task; | ||
148 | static struct task_struct *stutter_task; | ||
149 | static struct task_struct *fqs_task; | 101 | static struct task_struct *fqs_task; |
150 | static struct task_struct *boost_tasks[NR_CPUS]; | 102 | static struct task_struct *boost_tasks[NR_CPUS]; |
151 | static struct task_struct *shutdown_task; | ||
152 | #ifdef CONFIG_HOTPLUG_CPU | ||
153 | static struct task_struct *onoff_task; | ||
154 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | ||
155 | static struct task_struct *stall_task; | 103 | static struct task_struct *stall_task; |
156 | static struct task_struct **barrier_cbs_tasks; | 104 | static struct task_struct **barrier_cbs_tasks; |
157 | static struct task_struct *barrier_task; | 105 | static struct task_struct *barrier_task; |
@@ -170,10 +118,10 @@ static struct rcu_torture __rcu *rcu_torture_current; | |||
170 | static unsigned long rcu_torture_current_version; | 118 | static unsigned long rcu_torture_current_version; |
171 | static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN]; | 119 | static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN]; |
172 | static DEFINE_SPINLOCK(rcu_torture_lock); | 120 | static DEFINE_SPINLOCK(rcu_torture_lock); |
173 | static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) = | 121 | static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], |
174 | { 0 }; | 122 | rcu_torture_count) = { 0 }; |
175 | static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) = | 123 | static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], |
176 | { 0 }; | 124 | rcu_torture_batch) = { 0 }; |
177 | static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1]; | 125 | static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1]; |
178 | static atomic_t n_rcu_torture_alloc; | 126 | static atomic_t n_rcu_torture_alloc; |
179 | static atomic_t n_rcu_torture_alloc_fail; | 127 | static atomic_t n_rcu_torture_alloc_fail; |
@@ -186,22 +134,9 @@ static long n_rcu_torture_boost_rterror; | |||
186 | static long n_rcu_torture_boost_failure; | 134 | static long n_rcu_torture_boost_failure; |
187 | static long n_rcu_torture_boosts; | 135 | static long n_rcu_torture_boosts; |
188 | static long n_rcu_torture_timers; | 136 | static long n_rcu_torture_timers; |
189 | static long n_offline_attempts; | ||
190 | static long n_offline_successes; | ||
191 | static unsigned long sum_offline; | ||
192 | static int min_offline = -1; | ||
193 | static int max_offline; | ||
194 | static long n_online_attempts; | ||
195 | static long n_online_successes; | ||
196 | static unsigned long sum_online; | ||
197 | static int min_online = -1; | ||
198 | static int max_online; | ||
199 | static long n_barrier_attempts; | 137 | static long n_barrier_attempts; |
200 | static long n_barrier_successes; | 138 | static long n_barrier_successes; |
201 | static struct list_head rcu_torture_removed; | 139 | static struct list_head rcu_torture_removed; |
202 | static cpumask_var_t shuffle_tmp_mask; | ||
203 | |||
204 | static int stutter_pause_test; | ||
205 | 140 | ||
206 | #if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE) | 141 | #if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE) |
207 | #define RCUTORTURE_RUNNABLE_INIT 1 | 142 | #define RCUTORTURE_RUNNABLE_INIT 1 |
@@ -232,7 +167,6 @@ static u64 notrace rcu_trace_clock_local(void) | |||
232 | } | 167 | } |
233 | #endif /* #else #ifdef CONFIG_RCU_TRACE */ | 168 | #endif /* #else #ifdef CONFIG_RCU_TRACE */ |
234 | 169 | ||
235 | static unsigned long shutdown_time; /* jiffies to system shutdown. */ | ||
236 | static unsigned long boost_starttime; /* jiffies of next boost test start. */ | 170 | static unsigned long boost_starttime; /* jiffies of next boost test start. */ |
237 | DEFINE_MUTEX(boost_mutex); /* protect setting boost_starttime */ | 171 | DEFINE_MUTEX(boost_mutex); /* protect setting boost_starttime */ |
238 | /* and boost task create/destroy. */ | 172 | /* and boost task create/destroy. */ |
@@ -242,51 +176,6 @@ static atomic_t barrier_cbs_invoked; /* Barrier callbacks invoked. */ | |||
242 | static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */ | 176 | static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */ |
243 | static DECLARE_WAIT_QUEUE_HEAD(barrier_wq); | 177 | static DECLARE_WAIT_QUEUE_HEAD(barrier_wq); |
244 | 178 | ||
245 | /* Mediate rmmod and system shutdown. Concurrent rmmod & shutdown illegal! */ | ||
246 | |||
247 | #define FULLSTOP_DONTSTOP 0 /* Normal operation. */ | ||
248 | #define FULLSTOP_SHUTDOWN 1 /* System shutdown with rcutorture running. */ | ||
249 | #define FULLSTOP_RMMOD 2 /* Normal rmmod of rcutorture. */ | ||
250 | static int fullstop = FULLSTOP_RMMOD; | ||
251 | /* | ||
252 | * Protect fullstop transitions and spawning of kthreads. | ||
253 | */ | ||
254 | static DEFINE_MUTEX(fullstop_mutex); | ||
255 | |||
256 | /* Forward reference. */ | ||
257 | static void rcu_torture_cleanup(void); | ||
258 | |||
259 | /* | ||
260 | * Detect and respond to a system shutdown. | ||
261 | */ | ||
262 | static int | ||
263 | rcutorture_shutdown_notify(struct notifier_block *unused1, | ||
264 | unsigned long unused2, void *unused3) | ||
265 | { | ||
266 | mutex_lock(&fullstop_mutex); | ||
267 | if (fullstop == FULLSTOP_DONTSTOP) | ||
268 | fullstop = FULLSTOP_SHUTDOWN; | ||
269 | else | ||
270 | pr_warn(/* but going down anyway, so... */ | ||
271 | "Concurrent 'rmmod rcutorture' and shutdown illegal!\n"); | ||
272 | mutex_unlock(&fullstop_mutex); | ||
273 | return NOTIFY_DONE; | ||
274 | } | ||
275 | |||
276 | /* | ||
277 | * Absorb kthreads into a kernel function that won't return, so that | ||
278 | * they won't ever access module text or data again. | ||
279 | */ | ||
280 | static void rcutorture_shutdown_absorb(const char *title) | ||
281 | { | ||
282 | if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) { | ||
283 | pr_notice( | ||
284 | "rcutorture thread %s parking due to system shutdown\n", | ||
285 | title); | ||
286 | schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT); | ||
287 | } | ||
288 | } | ||
289 | |||
290 | /* | 179 | /* |
291 | * Allocate an element from the rcu_tortures pool. | 180 | * Allocate an element from the rcu_tortures pool. |
292 | */ | 181 | */ |
@@ -320,44 +209,6 @@ rcu_torture_free(struct rcu_torture *p) | |||
320 | spin_unlock_bh(&rcu_torture_lock); | 209 | spin_unlock_bh(&rcu_torture_lock); |
321 | } | 210 | } |
322 | 211 | ||
323 | struct rcu_random_state { | ||
324 | unsigned long rrs_state; | ||
325 | long rrs_count; | ||
326 | }; | ||
327 | |||
328 | #define RCU_RANDOM_MULT 39916801 /* prime */ | ||
329 | #define RCU_RANDOM_ADD 479001701 /* prime */ | ||
330 | #define RCU_RANDOM_REFRESH 10000 | ||
331 | |||
332 | #define DEFINE_RCU_RANDOM(name) struct rcu_random_state name = { 0, 0 } | ||
333 | |||
334 | /* | ||
335 | * Crude but fast random-number generator. Uses a linear congruential | ||
336 | * generator, with occasional help from cpu_clock(). | ||
337 | */ | ||
338 | static unsigned long | ||
339 | rcu_random(struct rcu_random_state *rrsp) | ||
340 | { | ||
341 | if (--rrsp->rrs_count < 0) { | ||
342 | rrsp->rrs_state += (unsigned long)local_clock(); | ||
343 | rrsp->rrs_count = RCU_RANDOM_REFRESH; | ||
344 | } | ||
345 | rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD; | ||
346 | return swahw32(rrsp->rrs_state); | ||
347 | } | ||
348 | |||
349 | static void | ||
350 | rcu_stutter_wait(const char *title) | ||
351 | { | ||
352 | while (stutter_pause_test || !rcutorture_runnable) { | ||
353 | if (rcutorture_runnable) | ||
354 | schedule_timeout_interruptible(1); | ||
355 | else | ||
356 | schedule_timeout_interruptible(round_jiffies_relative(HZ)); | ||
357 | rcutorture_shutdown_absorb(title); | ||
358 | } | ||
359 | } | ||
360 | |||
361 | /* | 212 | /* |
362 | * Operations vector for selecting different types of tests. | 213 | * Operations vector for selecting different types of tests. |
363 | */ | 214 | */ |
@@ -365,7 +216,7 @@ rcu_stutter_wait(const char *title) | |||
365 | struct rcu_torture_ops { | 216 | struct rcu_torture_ops { |
366 | void (*init)(void); | 217 | void (*init)(void); |
367 | int (*readlock)(void); | 218 | int (*readlock)(void); |
368 | void (*read_delay)(struct rcu_random_state *rrsp); | 219 | void (*read_delay)(struct torture_random_state *rrsp); |
369 | void (*readunlock)(int idx); | 220 | void (*readunlock)(int idx); |
370 | int (*completed)(void); | 221 | int (*completed)(void); |
371 | void (*deferred_free)(struct rcu_torture *p); | 222 | void (*deferred_free)(struct rcu_torture *p); |
@@ -392,7 +243,7 @@ static int rcu_torture_read_lock(void) __acquires(RCU) | |||
392 | return 0; | 243 | return 0; |
393 | } | 244 | } |
394 | 245 | ||
395 | static void rcu_read_delay(struct rcu_random_state *rrsp) | 246 | static void rcu_read_delay(struct torture_random_state *rrsp) |
396 | { | 247 | { |
397 | const unsigned long shortdelay_us = 200; | 248 | const unsigned long shortdelay_us = 200; |
398 | const unsigned long longdelay_ms = 50; | 249 | const unsigned long longdelay_ms = 50; |
@@ -401,12 +252,13 @@ static void rcu_read_delay(struct rcu_random_state *rrsp) | |||
401 | * period, and we want a long delay occasionally to trigger | 252 | * period, and we want a long delay occasionally to trigger |
402 | * force_quiescent_state. */ | 253 | * force_quiescent_state. */ |
403 | 254 | ||
404 | if (!(rcu_random(rrsp) % (nrealreaders * 2000 * longdelay_ms))) | 255 | if (!(torture_random(rrsp) % (nrealreaders * 2000 * longdelay_ms))) |
405 | mdelay(longdelay_ms); | 256 | mdelay(longdelay_ms); |
406 | if (!(rcu_random(rrsp) % (nrealreaders * 2 * shortdelay_us))) | 257 | if (!(torture_random(rrsp) % (nrealreaders * 2 * shortdelay_us))) |
407 | udelay(shortdelay_us); | 258 | udelay(shortdelay_us); |
408 | #ifdef CONFIG_PREEMPT | 259 | #ifdef CONFIG_PREEMPT |
409 | if (!preempt_count() && !(rcu_random(rrsp) % (nrealreaders * 20000))) | 260 | if (!preempt_count() && |
261 | !(torture_random(rrsp) % (nrealreaders * 20000))) | ||
410 | preempt_schedule(); /* No QS if preempt_disable() in effect */ | 262 | preempt_schedule(); /* No QS if preempt_disable() in effect */ |
411 | #endif | 263 | #endif |
412 | } | 264 | } |
@@ -427,7 +279,7 @@ rcu_torture_cb(struct rcu_head *p) | |||
427 | int i; | 279 | int i; |
428 | struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu); | 280 | struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu); |
429 | 281 | ||
430 | if (fullstop != FULLSTOP_DONTSTOP) { | 282 | if (torture_must_stop_irq()) { |
431 | /* Test is ending, just drop callbacks on the floor. */ | 283 | /* Test is ending, just drop callbacks on the floor. */ |
432 | /* The next initialization will pick up the pieces. */ | 284 | /* The next initialization will pick up the pieces. */ |
433 | return; | 285 | return; |
@@ -520,6 +372,48 @@ static struct rcu_torture_ops rcu_bh_ops = { | |||
520 | }; | 372 | }; |
521 | 373 | ||
522 | /* | 374 | /* |
375 | * Don't even think about trying any of these in real life!!! | ||
376 | * The names includes "busted", and they really means it! | ||
377 | * The only purpose of these functions is to provide a buggy RCU | ||
378 | * implementation to make sure that rcutorture correctly emits | ||
379 | * buggy-RCU error messages. | ||
380 | */ | ||
381 | static void rcu_busted_torture_deferred_free(struct rcu_torture *p) | ||
382 | { | ||
383 | /* This is a deliberate bug for testing purposes only! */ | ||
384 | rcu_torture_cb(&p->rtort_rcu); | ||
385 | } | ||
386 | |||
387 | static void synchronize_rcu_busted(void) | ||
388 | { | ||
389 | /* This is a deliberate bug for testing purposes only! */ | ||
390 | } | ||
391 | |||
392 | static void | ||
393 | call_rcu_busted(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) | ||
394 | { | ||
395 | /* This is a deliberate bug for testing purposes only! */ | ||
396 | func(head); | ||
397 | } | ||
398 | |||
399 | static struct rcu_torture_ops rcu_busted_ops = { | ||
400 | .init = rcu_sync_torture_init, | ||
401 | .readlock = rcu_torture_read_lock, | ||
402 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | ||
403 | .readunlock = rcu_torture_read_unlock, | ||
404 | .completed = rcu_no_completed, | ||
405 | .deferred_free = rcu_busted_torture_deferred_free, | ||
406 | .sync = synchronize_rcu_busted, | ||
407 | .exp_sync = synchronize_rcu_busted, | ||
408 | .call = call_rcu_busted, | ||
409 | .cb_barrier = NULL, | ||
410 | .fqs = NULL, | ||
411 | .stats = NULL, | ||
412 | .irq_capable = 1, | ||
413 | .name = "rcu_busted" | ||
414 | }; | ||
415 | |||
416 | /* | ||
523 | * Definitions for srcu torture testing. | 417 | * Definitions for srcu torture testing. |
524 | */ | 418 | */ |
525 | 419 | ||
@@ -530,7 +424,7 @@ static int srcu_torture_read_lock(void) __acquires(&srcu_ctl) | |||
530 | return srcu_read_lock(&srcu_ctl); | 424 | return srcu_read_lock(&srcu_ctl); |
531 | } | 425 | } |
532 | 426 | ||
533 | static void srcu_read_delay(struct rcu_random_state *rrsp) | 427 | static void srcu_read_delay(struct torture_random_state *rrsp) |
534 | { | 428 | { |
535 | long delay; | 429 | long delay; |
536 | const long uspertick = 1000000 / HZ; | 430 | const long uspertick = 1000000 / HZ; |
@@ -538,7 +432,8 @@ static void srcu_read_delay(struct rcu_random_state *rrsp) | |||
538 | 432 | ||
539 | /* We want there to be long-running readers, but not all the time. */ | 433 | /* We want there to be long-running readers, but not all the time. */ |
540 | 434 | ||
541 | delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay * uspertick); | 435 | delay = torture_random(rrsp) % |
436 | (nrealreaders * 2 * longdelay * uspertick); | ||
542 | if (!delay) | 437 | if (!delay) |
543 | schedule_timeout_interruptible(longdelay); | 438 | schedule_timeout_interruptible(longdelay); |
544 | else | 439 | else |
@@ -677,12 +572,12 @@ static int rcu_torture_boost(void *arg) | |||
677 | struct rcu_boost_inflight rbi = { .inflight = 0 }; | 572 | struct rcu_boost_inflight rbi = { .inflight = 0 }; |
678 | struct sched_param sp; | 573 | struct sched_param sp; |
679 | 574 | ||
680 | VERBOSE_PRINTK_STRING("rcu_torture_boost started"); | 575 | VERBOSE_TOROUT_STRING("rcu_torture_boost started"); |
681 | 576 | ||
682 | /* Set real-time priority. */ | 577 | /* Set real-time priority. */ |
683 | sp.sched_priority = 1; | 578 | sp.sched_priority = 1; |
684 | if (sched_setscheduler(current, SCHED_FIFO, &sp) < 0) { | 579 | if (sched_setscheduler(current, SCHED_FIFO, &sp) < 0) { |
685 | VERBOSE_PRINTK_STRING("rcu_torture_boost RT prio failed!"); | 580 | VERBOSE_TOROUT_STRING("rcu_torture_boost RT prio failed!"); |
686 | n_rcu_torture_boost_rterror++; | 581 | n_rcu_torture_boost_rterror++; |
687 | } | 582 | } |
688 | 583 | ||
@@ -693,9 +588,8 @@ static int rcu_torture_boost(void *arg) | |||
693 | oldstarttime = boost_starttime; | 588 | oldstarttime = boost_starttime; |
694 | while (ULONG_CMP_LT(jiffies, oldstarttime)) { | 589 | while (ULONG_CMP_LT(jiffies, oldstarttime)) { |
695 | schedule_timeout_interruptible(oldstarttime - jiffies); | 590 | schedule_timeout_interruptible(oldstarttime - jiffies); |
696 | rcu_stutter_wait("rcu_torture_boost"); | 591 | stutter_wait("rcu_torture_boost"); |
697 | if (kthread_should_stop() || | 592 | if (torture_must_stop()) |
698 | fullstop != FULLSTOP_DONTSTOP) | ||
699 | goto checkwait; | 593 | goto checkwait; |
700 | } | 594 | } |
701 | 595 | ||
@@ -710,15 +604,14 @@ static int rcu_torture_boost(void *arg) | |||
710 | call_rcu(&rbi.rcu, rcu_torture_boost_cb); | 604 | call_rcu(&rbi.rcu, rcu_torture_boost_cb); |
711 | if (jiffies - call_rcu_time > | 605 | if (jiffies - call_rcu_time > |
712 | test_boost_duration * HZ - HZ / 2) { | 606 | test_boost_duration * HZ - HZ / 2) { |
713 | VERBOSE_PRINTK_STRING("rcu_torture_boost boosting failed"); | 607 | VERBOSE_TOROUT_STRING("rcu_torture_boost boosting failed"); |
714 | n_rcu_torture_boost_failure++; | 608 | n_rcu_torture_boost_failure++; |
715 | } | 609 | } |
716 | call_rcu_time = jiffies; | 610 | call_rcu_time = jiffies; |
717 | } | 611 | } |
718 | cond_resched(); | 612 | cond_resched(); |
719 | rcu_stutter_wait("rcu_torture_boost"); | 613 | stutter_wait("rcu_torture_boost"); |
720 | if (kthread_should_stop() || | 614 | if (torture_must_stop()) |
721 | fullstop != FULLSTOP_DONTSTOP) | ||
722 | goto checkwait; | 615 | goto checkwait; |
723 | } | 616 | } |
724 | 617 | ||
@@ -742,16 +635,17 @@ static int rcu_torture_boost(void *arg) | |||
742 | } | 635 | } |
743 | 636 | ||
744 | /* Go do the stutter. */ | 637 | /* Go do the stutter. */ |
745 | checkwait: rcu_stutter_wait("rcu_torture_boost"); | 638 | checkwait: stutter_wait("rcu_torture_boost"); |
746 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); | 639 | } while (!torture_must_stop()); |
747 | 640 | ||
748 | /* Clean up and exit. */ | 641 | /* Clean up and exit. */ |
749 | VERBOSE_PRINTK_STRING("rcu_torture_boost task stopping"); | 642 | while (!kthread_should_stop() || rbi.inflight) { |
750 | rcutorture_shutdown_absorb("rcu_torture_boost"); | 643 | torture_shutdown_absorb("rcu_torture_boost"); |
751 | while (!kthread_should_stop() || rbi.inflight) | ||
752 | schedule_timeout_uninterruptible(1); | 644 | schedule_timeout_uninterruptible(1); |
645 | } | ||
753 | smp_mb(); /* order accesses to ->inflight before stack-frame death. */ | 646 | smp_mb(); /* order accesses to ->inflight before stack-frame death. */ |
754 | destroy_rcu_head_on_stack(&rbi.rcu); | 647 | destroy_rcu_head_on_stack(&rbi.rcu); |
648 | torture_kthread_stopping("rcu_torture_boost"); | ||
755 | return 0; | 649 | return 0; |
756 | } | 650 | } |
757 | 651 | ||
@@ -766,7 +660,7 @@ rcu_torture_fqs(void *arg) | |||
766 | unsigned long fqs_resume_time; | 660 | unsigned long fqs_resume_time; |
767 | int fqs_burst_remaining; | 661 | int fqs_burst_remaining; |
768 | 662 | ||
769 | VERBOSE_PRINTK_STRING("rcu_torture_fqs task started"); | 663 | VERBOSE_TOROUT_STRING("rcu_torture_fqs task started"); |
770 | do { | 664 | do { |
771 | fqs_resume_time = jiffies + fqs_stutter * HZ; | 665 | fqs_resume_time = jiffies + fqs_stutter * HZ; |
772 | while (ULONG_CMP_LT(jiffies, fqs_resume_time) && | 666 | while (ULONG_CMP_LT(jiffies, fqs_resume_time) && |
@@ -780,12 +674,9 @@ rcu_torture_fqs(void *arg) | |||
780 | udelay(fqs_holdoff); | 674 | udelay(fqs_holdoff); |
781 | fqs_burst_remaining -= fqs_holdoff; | 675 | fqs_burst_remaining -= fqs_holdoff; |
782 | } | 676 | } |
783 | rcu_stutter_wait("rcu_torture_fqs"); | 677 | stutter_wait("rcu_torture_fqs"); |
784 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); | 678 | } while (!torture_must_stop()); |
785 | VERBOSE_PRINTK_STRING("rcu_torture_fqs task stopping"); | 679 | torture_kthread_stopping("rcu_torture_fqs"); |
786 | rcutorture_shutdown_absorb("rcu_torture_fqs"); | ||
787 | while (!kthread_should_stop()) | ||
788 | schedule_timeout_uninterruptible(1); | ||
789 | return 0; | 680 | return 0; |
790 | } | 681 | } |
791 | 682 | ||
@@ -802,9 +693,9 @@ rcu_torture_writer(void *arg) | |||
802 | struct rcu_torture *rp; | 693 | struct rcu_torture *rp; |
803 | struct rcu_torture *rp1; | 694 | struct rcu_torture *rp1; |
804 | struct rcu_torture *old_rp; | 695 | struct rcu_torture *old_rp; |
805 | static DEFINE_RCU_RANDOM(rand); | 696 | static DEFINE_TORTURE_RANDOM(rand); |
806 | 697 | ||
807 | VERBOSE_PRINTK_STRING("rcu_torture_writer task started"); | 698 | VERBOSE_TOROUT_STRING("rcu_torture_writer task started"); |
808 | set_user_nice(current, 19); | 699 | set_user_nice(current, 19); |
809 | 700 | ||
810 | do { | 701 | do { |
@@ -813,7 +704,7 @@ rcu_torture_writer(void *arg) | |||
813 | if (rp == NULL) | 704 | if (rp == NULL) |
814 | continue; | 705 | continue; |
815 | rp->rtort_pipe_count = 0; | 706 | rp->rtort_pipe_count = 0; |
816 | udelay(rcu_random(&rand) & 0x3ff); | 707 | udelay(torture_random(&rand) & 0x3ff); |
817 | old_rp = rcu_dereference_check(rcu_torture_current, | 708 | old_rp = rcu_dereference_check(rcu_torture_current, |
818 | current == writer_task); | 709 | current == writer_task); |
819 | rp->rtort_mbtest = 1; | 710 | rp->rtort_mbtest = 1; |
@@ -826,7 +717,7 @@ rcu_torture_writer(void *arg) | |||
826 | atomic_inc(&rcu_torture_wcount[i]); | 717 | atomic_inc(&rcu_torture_wcount[i]); |
827 | old_rp->rtort_pipe_count++; | 718 | old_rp->rtort_pipe_count++; |
828 | if (gp_normal == gp_exp) | 719 | if (gp_normal == gp_exp) |
829 | exp = !!(rcu_random(&rand) & 0x80); | 720 | exp = !!(torture_random(&rand) & 0x80); |
830 | else | 721 | else |
831 | exp = gp_exp; | 722 | exp = gp_exp; |
832 | if (!exp) { | 723 | if (!exp) { |
@@ -852,12 +743,9 @@ rcu_torture_writer(void *arg) | |||
852 | } | 743 | } |
853 | } | 744 | } |
854 | rcutorture_record_progress(++rcu_torture_current_version); | 745 | rcutorture_record_progress(++rcu_torture_current_version); |
855 | rcu_stutter_wait("rcu_torture_writer"); | 746 | stutter_wait("rcu_torture_writer"); |
856 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); | 747 | } while (!torture_must_stop()); |
857 | VERBOSE_PRINTK_STRING("rcu_torture_writer task stopping"); | 748 | torture_kthread_stopping("rcu_torture_writer"); |
858 | rcutorture_shutdown_absorb("rcu_torture_writer"); | ||
859 | while (!kthread_should_stop()) | ||
860 | schedule_timeout_uninterruptible(1); | ||
861 | return 0; | 749 | return 0; |
862 | } | 750 | } |
863 | 751 | ||
@@ -868,19 +756,19 @@ rcu_torture_writer(void *arg) | |||
868 | static int | 756 | static int |
869 | rcu_torture_fakewriter(void *arg) | 757 | rcu_torture_fakewriter(void *arg) |
870 | { | 758 | { |
871 | DEFINE_RCU_RANDOM(rand); | 759 | DEFINE_TORTURE_RANDOM(rand); |
872 | 760 | ||
873 | VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started"); | 761 | VERBOSE_TOROUT_STRING("rcu_torture_fakewriter task started"); |
874 | set_user_nice(current, 19); | 762 | set_user_nice(current, 19); |
875 | 763 | ||
876 | do { | 764 | do { |
877 | schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10); | 765 | schedule_timeout_uninterruptible(1 + torture_random(&rand)%10); |
878 | udelay(rcu_random(&rand) & 0x3ff); | 766 | udelay(torture_random(&rand) & 0x3ff); |
879 | if (cur_ops->cb_barrier != NULL && | 767 | if (cur_ops->cb_barrier != NULL && |
880 | rcu_random(&rand) % (nfakewriters * 8) == 0) { | 768 | torture_random(&rand) % (nfakewriters * 8) == 0) { |
881 | cur_ops->cb_barrier(); | 769 | cur_ops->cb_barrier(); |
882 | } else if (gp_normal == gp_exp) { | 770 | } else if (gp_normal == gp_exp) { |
883 | if (rcu_random(&rand) & 0x80) | 771 | if (torture_random(&rand) & 0x80) |
884 | cur_ops->sync(); | 772 | cur_ops->sync(); |
885 | else | 773 | else |
886 | cur_ops->exp_sync(); | 774 | cur_ops->exp_sync(); |
@@ -889,13 +777,10 @@ rcu_torture_fakewriter(void *arg) | |||
889 | } else { | 777 | } else { |
890 | cur_ops->exp_sync(); | 778 | cur_ops->exp_sync(); |
891 | } | 779 | } |
892 | rcu_stutter_wait("rcu_torture_fakewriter"); | 780 | stutter_wait("rcu_torture_fakewriter"); |
893 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); | 781 | } while (!torture_must_stop()); |
894 | 782 | ||
895 | VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task stopping"); | 783 | torture_kthread_stopping("rcu_torture_fakewriter"); |
896 | rcutorture_shutdown_absorb("rcu_torture_fakewriter"); | ||
897 | while (!kthread_should_stop()) | ||
898 | schedule_timeout_uninterruptible(1); | ||
899 | return 0; | 784 | return 0; |
900 | } | 785 | } |
901 | 786 | ||
@@ -921,7 +806,7 @@ static void rcu_torture_timer(unsigned long unused) | |||
921 | int idx; | 806 | int idx; |
922 | int completed; | 807 | int completed; |
923 | int completed_end; | 808 | int completed_end; |
924 | static DEFINE_RCU_RANDOM(rand); | 809 | static DEFINE_TORTURE_RANDOM(rand); |
925 | static DEFINE_SPINLOCK(rand_lock); | 810 | static DEFINE_SPINLOCK(rand_lock); |
926 | struct rcu_torture *p; | 811 | struct rcu_torture *p; |
927 | int pipe_count; | 812 | int pipe_count; |
@@ -980,13 +865,13 @@ rcu_torture_reader(void *arg) | |||
980 | int completed; | 865 | int completed; |
981 | int completed_end; | 866 | int completed_end; |
982 | int idx; | 867 | int idx; |
983 | DEFINE_RCU_RANDOM(rand); | 868 | DEFINE_TORTURE_RANDOM(rand); |
984 | struct rcu_torture *p; | 869 | struct rcu_torture *p; |
985 | int pipe_count; | 870 | int pipe_count; |
986 | struct timer_list t; | 871 | struct timer_list t; |
987 | unsigned long long ts; | 872 | unsigned long long ts; |
988 | 873 | ||
989 | VERBOSE_PRINTK_STRING("rcu_torture_reader task started"); | 874 | VERBOSE_TOROUT_STRING("rcu_torture_reader task started"); |
990 | set_user_nice(current, 19); | 875 | set_user_nice(current, 19); |
991 | if (irqreader && cur_ops->irq_capable) | 876 | if (irqreader && cur_ops->irq_capable) |
992 | setup_timer_on_stack(&t, rcu_torture_timer, 0); | 877 | setup_timer_on_stack(&t, rcu_torture_timer, 0); |
@@ -1034,14 +919,11 @@ rcu_torture_reader(void *arg) | |||
1034 | preempt_enable(); | 919 | preempt_enable(); |
1035 | cur_ops->readunlock(idx); | 920 | cur_ops->readunlock(idx); |
1036 | schedule(); | 921 | schedule(); |
1037 | rcu_stutter_wait("rcu_torture_reader"); | 922 | stutter_wait("rcu_torture_reader"); |
1038 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); | 923 | } while (!torture_must_stop()); |
1039 | VERBOSE_PRINTK_STRING("rcu_torture_reader task stopping"); | ||
1040 | rcutorture_shutdown_absorb("rcu_torture_reader"); | ||
1041 | if (irqreader && cur_ops->irq_capable) | 924 | if (irqreader && cur_ops->irq_capable) |
1042 | del_timer_sync(&t); | 925 | del_timer_sync(&t); |
1043 | while (!kthread_should_stop()) | 926 | torture_kthread_stopping("rcu_torture_reader"); |
1044 | schedule_timeout_uninterruptible(1); | ||
1045 | return 0; | 927 | return 0; |
1046 | } | 928 | } |
1047 | 929 | ||
@@ -1083,13 +965,7 @@ rcu_torture_printk(char *page) | |||
1083 | n_rcu_torture_boost_failure, | 965 | n_rcu_torture_boost_failure, |
1084 | n_rcu_torture_boosts, | 966 | n_rcu_torture_boosts, |
1085 | n_rcu_torture_timers); | 967 | n_rcu_torture_timers); |
1086 | page += sprintf(page, | 968 | page = torture_onoff_stats(page); |
1087 | "onoff: %ld/%ld:%ld/%ld %d,%d:%d,%d %lu:%lu (HZ=%d) ", | ||
1088 | n_online_successes, n_online_attempts, | ||
1089 | n_offline_successes, n_offline_attempts, | ||
1090 | min_online, max_online, | ||
1091 | min_offline, max_offline, | ||
1092 | sum_online, sum_offline, HZ); | ||
1093 | page += sprintf(page, "barrier: %ld/%ld:%ld", | 969 | page += sprintf(page, "barrier: %ld/%ld:%ld", |
1094 | n_barrier_successes, | 970 | n_barrier_successes, |
1095 | n_barrier_attempts, | 971 | n_barrier_attempts, |
@@ -1150,123 +1026,17 @@ rcu_torture_stats_print(void) | |||
1150 | /* | 1026 | /* |
1151 | * Periodically prints torture statistics, if periodic statistics printing | 1027 | * Periodically prints torture statistics, if periodic statistics printing |
1152 | * was specified via the stat_interval module parameter. | 1028 | * was specified via the stat_interval module parameter. |
1153 | * | ||
1154 | * No need to worry about fullstop here, since this one doesn't reference | ||
1155 | * volatile state or register callbacks. | ||
1156 | */ | 1029 | */ |
1157 | static int | 1030 | static int |
1158 | rcu_torture_stats(void *arg) | 1031 | rcu_torture_stats(void *arg) |
1159 | { | 1032 | { |
1160 | VERBOSE_PRINTK_STRING("rcu_torture_stats task started"); | 1033 | VERBOSE_TOROUT_STRING("rcu_torture_stats task started"); |
1161 | do { | 1034 | do { |
1162 | schedule_timeout_interruptible(stat_interval * HZ); | 1035 | schedule_timeout_interruptible(stat_interval * HZ); |
1163 | rcu_torture_stats_print(); | 1036 | rcu_torture_stats_print(); |
1164 | rcutorture_shutdown_absorb("rcu_torture_stats"); | 1037 | torture_shutdown_absorb("rcu_torture_stats"); |
1165 | } while (!kthread_should_stop()); | 1038 | } while (!torture_must_stop()); |
1166 | VERBOSE_PRINTK_STRING("rcu_torture_stats task stopping"); | 1039 | torture_kthread_stopping("rcu_torture_stats"); |
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | static int rcu_idle_cpu; /* Force all torture tasks off this CPU */ | ||
1171 | |||
1172 | /* Shuffle tasks such that we allow @rcu_idle_cpu to become idle. A special case | ||
1173 | * is when @rcu_idle_cpu = -1, when we allow the tasks to run on all CPUs. | ||
1174 | */ | ||
1175 | static void rcu_torture_shuffle_tasks(void) | ||
1176 | { | ||
1177 | int i; | ||
1178 | |||
1179 | cpumask_setall(shuffle_tmp_mask); | ||
1180 | get_online_cpus(); | ||
1181 | |||
1182 | /* No point in shuffling if there is only one online CPU (ex: UP) */ | ||
1183 | if (num_online_cpus() == 1) { | ||
1184 | put_online_cpus(); | ||
1185 | return; | ||
1186 | } | ||
1187 | |||
1188 | if (rcu_idle_cpu != -1) | ||
1189 | cpumask_clear_cpu(rcu_idle_cpu, shuffle_tmp_mask); | ||
1190 | |||
1191 | set_cpus_allowed_ptr(current, shuffle_tmp_mask); | ||
1192 | |||
1193 | if (reader_tasks) { | ||
1194 | for (i = 0; i < nrealreaders; i++) | ||
1195 | if (reader_tasks[i]) | ||
1196 | set_cpus_allowed_ptr(reader_tasks[i], | ||
1197 | shuffle_tmp_mask); | ||
1198 | } | ||
1199 | if (fakewriter_tasks) { | ||
1200 | for (i = 0; i < nfakewriters; i++) | ||
1201 | if (fakewriter_tasks[i]) | ||
1202 | set_cpus_allowed_ptr(fakewriter_tasks[i], | ||
1203 | shuffle_tmp_mask); | ||
1204 | } | ||
1205 | if (writer_task) | ||
1206 | set_cpus_allowed_ptr(writer_task, shuffle_tmp_mask); | ||
1207 | if (stats_task) | ||
1208 | set_cpus_allowed_ptr(stats_task, shuffle_tmp_mask); | ||
1209 | if (stutter_task) | ||
1210 | set_cpus_allowed_ptr(stutter_task, shuffle_tmp_mask); | ||
1211 | if (fqs_task) | ||
1212 | set_cpus_allowed_ptr(fqs_task, shuffle_tmp_mask); | ||
1213 | if (shutdown_task) | ||
1214 | set_cpus_allowed_ptr(shutdown_task, shuffle_tmp_mask); | ||
1215 | #ifdef CONFIG_HOTPLUG_CPU | ||
1216 | if (onoff_task) | ||
1217 | set_cpus_allowed_ptr(onoff_task, shuffle_tmp_mask); | ||
1218 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | ||
1219 | if (stall_task) | ||
1220 | set_cpus_allowed_ptr(stall_task, shuffle_tmp_mask); | ||
1221 | if (barrier_cbs_tasks) | ||
1222 | for (i = 0; i < n_barrier_cbs; i++) | ||
1223 | if (barrier_cbs_tasks[i]) | ||
1224 | set_cpus_allowed_ptr(barrier_cbs_tasks[i], | ||
1225 | shuffle_tmp_mask); | ||
1226 | if (barrier_task) | ||
1227 | set_cpus_allowed_ptr(barrier_task, shuffle_tmp_mask); | ||
1228 | |||
1229 | if (rcu_idle_cpu == -1) | ||
1230 | rcu_idle_cpu = num_online_cpus() - 1; | ||
1231 | else | ||
1232 | rcu_idle_cpu--; | ||
1233 | |||
1234 | put_online_cpus(); | ||
1235 | } | ||
1236 | |||
1237 | /* Shuffle tasks across CPUs, with the intent of allowing each CPU in the | ||
1238 | * system to become idle at a time and cut off its timer ticks. This is meant | ||
1239 | * to test the support for such tickless idle CPU in RCU. | ||
1240 | */ | ||
1241 | static int | ||
1242 | rcu_torture_shuffle(void *arg) | ||
1243 | { | ||
1244 | VERBOSE_PRINTK_STRING("rcu_torture_shuffle task started"); | ||
1245 | do { | ||
1246 | schedule_timeout_interruptible(shuffle_interval * HZ); | ||
1247 | rcu_torture_shuffle_tasks(); | ||
1248 | rcutorture_shutdown_absorb("rcu_torture_shuffle"); | ||
1249 | } while (!kthread_should_stop()); | ||
1250 | VERBOSE_PRINTK_STRING("rcu_torture_shuffle task stopping"); | ||
1251 | return 0; | ||
1252 | } | ||
1253 | |||
1254 | /* Cause the rcutorture test to "stutter", starting and stopping all | ||
1255 | * threads periodically. | ||
1256 | */ | ||
1257 | static int | ||
1258 | rcu_torture_stutter(void *arg) | ||
1259 | { | ||
1260 | VERBOSE_PRINTK_STRING("rcu_torture_stutter task started"); | ||
1261 | do { | ||
1262 | schedule_timeout_interruptible(stutter * HZ); | ||
1263 | stutter_pause_test = 1; | ||
1264 | if (!kthread_should_stop()) | ||
1265 | schedule_timeout_interruptible(stutter * HZ); | ||
1266 | stutter_pause_test = 0; | ||
1267 | rcutorture_shutdown_absorb("rcu_torture_stutter"); | ||
1268 | } while (!kthread_should_stop()); | ||
1269 | VERBOSE_PRINTK_STRING("rcu_torture_stutter task stopping"); | ||
1270 | return 0; | 1040 | return 0; |
1271 | } | 1041 | } |
1272 | 1042 | ||
@@ -1293,10 +1063,6 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag) | |||
1293 | onoff_interval, onoff_holdoff); | 1063 | onoff_interval, onoff_holdoff); |
1294 | } | 1064 | } |
1295 | 1065 | ||
1296 | static struct notifier_block rcutorture_shutdown_nb = { | ||
1297 | .notifier_call = rcutorture_shutdown_notify, | ||
1298 | }; | ||
1299 | |||
1300 | static void rcutorture_booster_cleanup(int cpu) | 1066 | static void rcutorture_booster_cleanup(int cpu) |
1301 | { | 1067 | { |
1302 | struct task_struct *t; | 1068 | struct task_struct *t; |
@@ -1304,14 +1070,12 @@ static void rcutorture_booster_cleanup(int cpu) | |||
1304 | if (boost_tasks[cpu] == NULL) | 1070 | if (boost_tasks[cpu] == NULL) |
1305 | return; | 1071 | return; |
1306 | mutex_lock(&boost_mutex); | 1072 | mutex_lock(&boost_mutex); |
1307 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_boost task"); | ||
1308 | t = boost_tasks[cpu]; | 1073 | t = boost_tasks[cpu]; |
1309 | boost_tasks[cpu] = NULL; | 1074 | boost_tasks[cpu] = NULL; |
1310 | mutex_unlock(&boost_mutex); | 1075 | mutex_unlock(&boost_mutex); |
1311 | 1076 | ||
1312 | /* This must be outside of the mutex, otherwise deadlock! */ | 1077 | /* This must be outside of the mutex, otherwise deadlock! */ |
1313 | kthread_stop(t); | 1078 | torture_stop_kthread(rcu_torture_boost, t); |
1314 | boost_tasks[cpu] = NULL; | ||
1315 | } | 1079 | } |
1316 | 1080 | ||
1317 | static int rcutorture_booster_init(int cpu) | 1081 | static int rcutorture_booster_init(int cpu) |
@@ -1323,13 +1087,13 @@ static int rcutorture_booster_init(int cpu) | |||
1323 | 1087 | ||
1324 | /* Don't allow time recalculation while creating a new task. */ | 1088 | /* Don't allow time recalculation while creating a new task. */ |
1325 | mutex_lock(&boost_mutex); | 1089 | mutex_lock(&boost_mutex); |
1326 | VERBOSE_PRINTK_STRING("Creating rcu_torture_boost task"); | 1090 | VERBOSE_TOROUT_STRING("Creating rcu_torture_boost task"); |
1327 | boost_tasks[cpu] = kthread_create_on_node(rcu_torture_boost, NULL, | 1091 | boost_tasks[cpu] = kthread_create_on_node(rcu_torture_boost, NULL, |
1328 | cpu_to_node(cpu), | 1092 | cpu_to_node(cpu), |
1329 | "rcu_torture_boost"); | 1093 | "rcu_torture_boost"); |
1330 | if (IS_ERR(boost_tasks[cpu])) { | 1094 | if (IS_ERR(boost_tasks[cpu])) { |
1331 | retval = PTR_ERR(boost_tasks[cpu]); | 1095 | retval = PTR_ERR(boost_tasks[cpu]); |
1332 | VERBOSE_PRINTK_STRING("rcu_torture_boost task create failed"); | 1096 | VERBOSE_TOROUT_STRING("rcu_torture_boost task create failed"); |
1333 | n_rcu_torture_boost_ktrerror++; | 1097 | n_rcu_torture_boost_ktrerror++; |
1334 | boost_tasks[cpu] = NULL; | 1098 | boost_tasks[cpu] = NULL; |
1335 | mutex_unlock(&boost_mutex); | 1099 | mutex_unlock(&boost_mutex); |
@@ -1342,175 +1106,6 @@ static int rcutorture_booster_init(int cpu) | |||
1342 | } | 1106 | } |
1343 | 1107 | ||
1344 | /* | 1108 | /* |
1345 | * Cause the rcutorture test to shutdown the system after the test has | ||
1346 | * run for the time specified by the shutdown_secs module parameter. | ||
1347 | */ | ||
1348 | static int | ||
1349 | rcu_torture_shutdown(void *arg) | ||
1350 | { | ||
1351 | long delta; | ||
1352 | unsigned long jiffies_snap; | ||
1353 | |||
1354 | VERBOSE_PRINTK_STRING("rcu_torture_shutdown task started"); | ||
1355 | jiffies_snap = jiffies; | ||
1356 | while (ULONG_CMP_LT(jiffies_snap, shutdown_time) && | ||
1357 | !kthread_should_stop()) { | ||
1358 | delta = shutdown_time - jiffies_snap; | ||
1359 | if (verbose) | ||
1360 | pr_alert("%s" TORTURE_FLAG | ||
1361 | "rcu_torture_shutdown task: %lu jiffies remaining\n", | ||
1362 | torture_type, delta); | ||
1363 | schedule_timeout_interruptible(delta); | ||
1364 | jiffies_snap = jiffies; | ||
1365 | } | ||
1366 | if (kthread_should_stop()) { | ||
1367 | VERBOSE_PRINTK_STRING("rcu_torture_shutdown task stopping"); | ||
1368 | return 0; | ||
1369 | } | ||
1370 | |||
1371 | /* OK, shut down the system. */ | ||
1372 | |||
1373 | VERBOSE_PRINTK_STRING("rcu_torture_shutdown task shutting down system"); | ||
1374 | shutdown_task = NULL; /* Avoid self-kill deadlock. */ | ||
1375 | rcu_torture_cleanup(); /* Get the success/failure message. */ | ||
1376 | kernel_power_off(); /* Shut down the system. */ | ||
1377 | return 0; | ||
1378 | } | ||
1379 | |||
1380 | #ifdef CONFIG_HOTPLUG_CPU | ||
1381 | |||
1382 | /* | ||
1383 | * Execute random CPU-hotplug operations at the interval specified | ||
1384 | * by the onoff_interval. | ||
1385 | */ | ||
1386 | static int | ||
1387 | rcu_torture_onoff(void *arg) | ||
1388 | { | ||
1389 | int cpu; | ||
1390 | unsigned long delta; | ||
1391 | int maxcpu = -1; | ||
1392 | DEFINE_RCU_RANDOM(rand); | ||
1393 | int ret; | ||
1394 | unsigned long starttime; | ||
1395 | |||
1396 | VERBOSE_PRINTK_STRING("rcu_torture_onoff task started"); | ||
1397 | for_each_online_cpu(cpu) | ||
1398 | maxcpu = cpu; | ||
1399 | WARN_ON(maxcpu < 0); | ||
1400 | if (onoff_holdoff > 0) { | ||
1401 | VERBOSE_PRINTK_STRING("rcu_torture_onoff begin holdoff"); | ||
1402 | schedule_timeout_interruptible(onoff_holdoff * HZ); | ||
1403 | VERBOSE_PRINTK_STRING("rcu_torture_onoff end holdoff"); | ||
1404 | } | ||
1405 | while (!kthread_should_stop()) { | ||
1406 | cpu = (rcu_random(&rand) >> 4) % (maxcpu + 1); | ||
1407 | if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) { | ||
1408 | if (verbose) | ||
1409 | pr_alert("%s" TORTURE_FLAG | ||
1410 | "rcu_torture_onoff task: offlining %d\n", | ||
1411 | torture_type, cpu); | ||
1412 | starttime = jiffies; | ||
1413 | n_offline_attempts++; | ||
1414 | ret = cpu_down(cpu); | ||
1415 | if (ret) { | ||
1416 | if (verbose) | ||
1417 | pr_alert("%s" TORTURE_FLAG | ||
1418 | "rcu_torture_onoff task: offline %d failed: errno %d\n", | ||
1419 | torture_type, cpu, ret); | ||
1420 | } else { | ||
1421 | if (verbose) | ||
1422 | pr_alert("%s" TORTURE_FLAG | ||
1423 | "rcu_torture_onoff task: offlined %d\n", | ||
1424 | torture_type, cpu); | ||
1425 | n_offline_successes++; | ||
1426 | delta = jiffies - starttime; | ||
1427 | sum_offline += delta; | ||
1428 | if (min_offline < 0) { | ||
1429 | min_offline = delta; | ||
1430 | max_offline = delta; | ||
1431 | } | ||
1432 | if (min_offline > delta) | ||
1433 | min_offline = delta; | ||
1434 | if (max_offline < delta) | ||
1435 | max_offline = delta; | ||
1436 | } | ||
1437 | } else if (cpu_is_hotpluggable(cpu)) { | ||
1438 | if (verbose) | ||
1439 | pr_alert("%s" TORTURE_FLAG | ||
1440 | "rcu_torture_onoff task: onlining %d\n", | ||
1441 | torture_type, cpu); | ||
1442 | starttime = jiffies; | ||
1443 | n_online_attempts++; | ||
1444 | ret = cpu_up(cpu); | ||
1445 | if (ret) { | ||
1446 | if (verbose) | ||
1447 | pr_alert("%s" TORTURE_FLAG | ||
1448 | "rcu_torture_onoff task: online %d failed: errno %d\n", | ||
1449 | torture_type, cpu, ret); | ||
1450 | } else { | ||
1451 | if (verbose) | ||
1452 | pr_alert("%s" TORTURE_FLAG | ||
1453 | "rcu_torture_onoff task: onlined %d\n", | ||
1454 | torture_type, cpu); | ||
1455 | n_online_successes++; | ||
1456 | delta = jiffies - starttime; | ||
1457 | sum_online += delta; | ||
1458 | if (min_online < 0) { | ||
1459 | min_online = delta; | ||
1460 | max_online = delta; | ||
1461 | } | ||
1462 | if (min_online > delta) | ||
1463 | min_online = delta; | ||
1464 | if (max_online < delta) | ||
1465 | max_online = delta; | ||
1466 | } | ||
1467 | } | ||
1468 | schedule_timeout_interruptible(onoff_interval * HZ); | ||
1469 | } | ||
1470 | VERBOSE_PRINTK_STRING("rcu_torture_onoff task stopping"); | ||
1471 | return 0; | ||
1472 | } | ||
1473 | |||
1474 | static int | ||
1475 | rcu_torture_onoff_init(void) | ||
1476 | { | ||
1477 | int ret; | ||
1478 | |||
1479 | if (onoff_interval <= 0) | ||
1480 | return 0; | ||
1481 | onoff_task = kthread_run(rcu_torture_onoff, NULL, "rcu_torture_onoff"); | ||
1482 | if (IS_ERR(onoff_task)) { | ||
1483 | ret = PTR_ERR(onoff_task); | ||
1484 | onoff_task = NULL; | ||
1485 | return ret; | ||
1486 | } | ||
1487 | return 0; | ||
1488 | } | ||
1489 | |||
1490 | static void rcu_torture_onoff_cleanup(void) | ||
1491 | { | ||
1492 | if (onoff_task == NULL) | ||
1493 | return; | ||
1494 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_onoff task"); | ||
1495 | kthread_stop(onoff_task); | ||
1496 | onoff_task = NULL; | ||
1497 | } | ||
1498 | |||
1499 | #else /* #ifdef CONFIG_HOTPLUG_CPU */ | ||
1500 | |||
1501 | static int | ||
1502 | rcu_torture_onoff_init(void) | ||
1503 | { | ||
1504 | return 0; | ||
1505 | } | ||
1506 | |||
1507 | static void rcu_torture_onoff_cleanup(void) | ||
1508 | { | ||
1509 | } | ||
1510 | |||
1511 | #endif /* #else #ifdef CONFIG_HOTPLUG_CPU */ | ||
1512 | |||
1513 | /* | ||
1514 | * CPU-stall kthread. It waits as specified by stall_cpu_holdoff, then | 1109 | * CPU-stall kthread. It waits as specified by stall_cpu_holdoff, then |
1515 | * induces a CPU stall for the time specified by stall_cpu. | 1110 | * induces a CPU stall for the time specified by stall_cpu. |
1516 | */ | 1111 | */ |
@@ -1518,11 +1113,11 @@ static int rcu_torture_stall(void *args) | |||
1518 | { | 1113 | { |
1519 | unsigned long stop_at; | 1114 | unsigned long stop_at; |
1520 | 1115 | ||
1521 | VERBOSE_PRINTK_STRING("rcu_torture_stall task started"); | 1116 | VERBOSE_TOROUT_STRING("rcu_torture_stall task started"); |
1522 | if (stall_cpu_holdoff > 0) { | 1117 | if (stall_cpu_holdoff > 0) { |
1523 | VERBOSE_PRINTK_STRING("rcu_torture_stall begin holdoff"); | 1118 | VERBOSE_TOROUT_STRING("rcu_torture_stall begin holdoff"); |
1524 | schedule_timeout_interruptible(stall_cpu_holdoff * HZ); | 1119 | schedule_timeout_interruptible(stall_cpu_holdoff * HZ); |
1525 | VERBOSE_PRINTK_STRING("rcu_torture_stall end holdoff"); | 1120 | VERBOSE_TOROUT_STRING("rcu_torture_stall end holdoff"); |
1526 | } | 1121 | } |
1527 | if (!kthread_should_stop()) { | 1122 | if (!kthread_should_stop()) { |
1528 | stop_at = get_seconds() + stall_cpu; | 1123 | stop_at = get_seconds() + stall_cpu; |
@@ -1536,7 +1131,7 @@ static int rcu_torture_stall(void *args) | |||
1536 | rcu_read_unlock(); | 1131 | rcu_read_unlock(); |
1537 | pr_alert("rcu_torture_stall end.\n"); | 1132 | pr_alert("rcu_torture_stall end.\n"); |
1538 | } | 1133 | } |
1539 | rcutorture_shutdown_absorb("rcu_torture_stall"); | 1134 | torture_shutdown_absorb("rcu_torture_stall"); |
1540 | while (!kthread_should_stop()) | 1135 | while (!kthread_should_stop()) |
1541 | schedule_timeout_interruptible(10 * HZ); | 1136 | schedule_timeout_interruptible(10 * HZ); |
1542 | return 0; | 1137 | return 0; |
@@ -1545,27 +1140,9 @@ static int rcu_torture_stall(void *args) | |||
1545 | /* Spawn CPU-stall kthread, if stall_cpu specified. */ | 1140 | /* Spawn CPU-stall kthread, if stall_cpu specified. */ |
1546 | static int __init rcu_torture_stall_init(void) | 1141 | static int __init rcu_torture_stall_init(void) |
1547 | { | 1142 | { |
1548 | int ret; | ||
1549 | |||
1550 | if (stall_cpu <= 0) | 1143 | if (stall_cpu <= 0) |
1551 | return 0; | 1144 | return 0; |
1552 | stall_task = kthread_run(rcu_torture_stall, NULL, "rcu_torture_stall"); | 1145 | return torture_create_kthread(rcu_torture_stall, NULL, stall_task); |
1553 | if (IS_ERR(stall_task)) { | ||
1554 | ret = PTR_ERR(stall_task); | ||
1555 | stall_task = NULL; | ||
1556 | return ret; | ||
1557 | } | ||
1558 | return 0; | ||
1559 | } | ||
1560 | |||
1561 | /* Clean up after the CPU-stall kthread, if one was spawned. */ | ||
1562 | static void rcu_torture_stall_cleanup(void) | ||
1563 | { | ||
1564 | if (stall_task == NULL) | ||
1565 | return; | ||
1566 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_stall_task."); | ||
1567 | kthread_stop(stall_task); | ||
1568 | stall_task = NULL; | ||
1569 | } | 1146 | } |
1570 | 1147 | ||
1571 | /* Callback function for RCU barrier testing. */ | 1148 | /* Callback function for RCU barrier testing. */ |
@@ -1583,28 +1160,24 @@ static int rcu_torture_barrier_cbs(void *arg) | |||
1583 | struct rcu_head rcu; | 1160 | struct rcu_head rcu; |
1584 | 1161 | ||
1585 | init_rcu_head_on_stack(&rcu); | 1162 | init_rcu_head_on_stack(&rcu); |
1586 | VERBOSE_PRINTK_STRING("rcu_torture_barrier_cbs task started"); | 1163 | VERBOSE_TOROUT_STRING("rcu_torture_barrier_cbs task started"); |
1587 | set_user_nice(current, 19); | 1164 | set_user_nice(current, 19); |
1588 | do { | 1165 | do { |
1589 | wait_event(barrier_cbs_wq[myid], | 1166 | wait_event(barrier_cbs_wq[myid], |
1590 | (newphase = | 1167 | (newphase = |
1591 | ACCESS_ONCE(barrier_phase)) != lastphase || | 1168 | ACCESS_ONCE(barrier_phase)) != lastphase || |
1592 | kthread_should_stop() || | 1169 | torture_must_stop()); |
1593 | fullstop != FULLSTOP_DONTSTOP); | ||
1594 | lastphase = newphase; | 1170 | lastphase = newphase; |
1595 | smp_mb(); /* ensure barrier_phase load before ->call(). */ | 1171 | smp_mb(); /* ensure barrier_phase load before ->call(). */ |
1596 | if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP) | 1172 | if (torture_must_stop()) |
1597 | break; | 1173 | break; |
1598 | cur_ops->call(&rcu, rcu_torture_barrier_cbf); | 1174 | cur_ops->call(&rcu, rcu_torture_barrier_cbf); |
1599 | if (atomic_dec_and_test(&barrier_cbs_count)) | 1175 | if (atomic_dec_and_test(&barrier_cbs_count)) |
1600 | wake_up(&barrier_wq); | 1176 | wake_up(&barrier_wq); |
1601 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); | 1177 | } while (!torture_must_stop()); |
1602 | VERBOSE_PRINTK_STRING("rcu_torture_barrier_cbs task stopping"); | ||
1603 | rcutorture_shutdown_absorb("rcu_torture_barrier_cbs"); | ||
1604 | while (!kthread_should_stop()) | ||
1605 | schedule_timeout_interruptible(1); | ||
1606 | cur_ops->cb_barrier(); | 1178 | cur_ops->cb_barrier(); |
1607 | destroy_rcu_head_on_stack(&rcu); | 1179 | destroy_rcu_head_on_stack(&rcu); |
1180 | torture_kthread_stopping("rcu_torture_barrier_cbs"); | ||
1608 | return 0; | 1181 | return 0; |
1609 | } | 1182 | } |
1610 | 1183 | ||
@@ -1613,7 +1186,7 @@ static int rcu_torture_barrier(void *arg) | |||
1613 | { | 1186 | { |
1614 | int i; | 1187 | int i; |
1615 | 1188 | ||
1616 | VERBOSE_PRINTK_STRING("rcu_torture_barrier task starting"); | 1189 | VERBOSE_TOROUT_STRING("rcu_torture_barrier task starting"); |
1617 | do { | 1190 | do { |
1618 | atomic_set(&barrier_cbs_invoked, 0); | 1191 | atomic_set(&barrier_cbs_invoked, 0); |
1619 | atomic_set(&barrier_cbs_count, n_barrier_cbs); | 1192 | atomic_set(&barrier_cbs_count, n_barrier_cbs); |
@@ -1623,9 +1196,8 @@ static int rcu_torture_barrier(void *arg) | |||
1623 | wake_up(&barrier_cbs_wq[i]); | 1196 | wake_up(&barrier_cbs_wq[i]); |
1624 | wait_event(barrier_wq, | 1197 | wait_event(barrier_wq, |
1625 | atomic_read(&barrier_cbs_count) == 0 || | 1198 | atomic_read(&barrier_cbs_count) == 0 || |
1626 | kthread_should_stop() || | 1199 | torture_must_stop()); |
1627 | fullstop != FULLSTOP_DONTSTOP); | 1200 | if (torture_must_stop()) |
1628 | if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP) | ||
1629 | break; | 1201 | break; |
1630 | n_barrier_attempts++; | 1202 | n_barrier_attempts++; |
1631 | cur_ops->cb_barrier(); /* Implies smp_mb() for wait_event(). */ | 1203 | cur_ops->cb_barrier(); /* Implies smp_mb() for wait_event(). */ |
@@ -1635,11 +1207,8 @@ static int rcu_torture_barrier(void *arg) | |||
1635 | } | 1207 | } |
1636 | n_barrier_successes++; | 1208 | n_barrier_successes++; |
1637 | schedule_timeout_interruptible(HZ / 10); | 1209 | schedule_timeout_interruptible(HZ / 10); |
1638 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); | 1210 | } while (!torture_must_stop()); |
1639 | VERBOSE_PRINTK_STRING("rcu_torture_barrier task stopping"); | 1211 | torture_kthread_stopping("rcu_torture_barrier"); |
1640 | rcutorture_shutdown_absorb("rcu_torture_barrier"); | ||
1641 | while (!kthread_should_stop()) | ||
1642 | schedule_timeout_interruptible(1); | ||
1643 | return 0; | 1212 | return 0; |
1644 | } | 1213 | } |
1645 | 1214 | ||
@@ -1672,24 +1241,13 @@ static int rcu_torture_barrier_init(void) | |||
1672 | return -ENOMEM; | 1241 | return -ENOMEM; |
1673 | for (i = 0; i < n_barrier_cbs; i++) { | 1242 | for (i = 0; i < n_barrier_cbs; i++) { |
1674 | init_waitqueue_head(&barrier_cbs_wq[i]); | 1243 | init_waitqueue_head(&barrier_cbs_wq[i]); |
1675 | barrier_cbs_tasks[i] = kthread_run(rcu_torture_barrier_cbs, | 1244 | ret = torture_create_kthread(rcu_torture_barrier_cbs, |
1676 | (void *)(long)i, | 1245 | (void *)(long)i, |
1677 | "rcu_torture_barrier_cbs"); | 1246 | barrier_cbs_tasks[i]); |
1678 | if (IS_ERR(barrier_cbs_tasks[i])) { | 1247 | if (ret) |
1679 | ret = PTR_ERR(barrier_cbs_tasks[i]); | ||
1680 | VERBOSE_PRINTK_ERRSTRING("Failed to create rcu_torture_barrier_cbs"); | ||
1681 | barrier_cbs_tasks[i] = NULL; | ||
1682 | return ret; | 1248 | return ret; |
1683 | } | ||
1684 | } | 1249 | } |
1685 | barrier_task = kthread_run(rcu_torture_barrier, NULL, | 1250 | return torture_create_kthread(rcu_torture_barrier, NULL, barrier_task); |
1686 | "rcu_torture_barrier"); | ||
1687 | if (IS_ERR(barrier_task)) { | ||
1688 | ret = PTR_ERR(barrier_task); | ||
1689 | VERBOSE_PRINTK_ERRSTRING("Failed to create rcu_torture_barrier"); | ||
1690 | barrier_task = NULL; | ||
1691 | } | ||
1692 | return 0; | ||
1693 | } | 1251 | } |
1694 | 1252 | ||
1695 | /* Clean up after RCU barrier testing. */ | 1253 | /* Clean up after RCU barrier testing. */ |
@@ -1697,19 +1255,11 @@ static void rcu_torture_barrier_cleanup(void) | |||
1697 | { | 1255 | { |
1698 | int i; | 1256 | int i; |
1699 | 1257 | ||
1700 | if (barrier_task != NULL) { | 1258 | torture_stop_kthread(rcu_torture_barrier, barrier_task); |
1701 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_barrier task"); | ||
1702 | kthread_stop(barrier_task); | ||
1703 | barrier_task = NULL; | ||
1704 | } | ||
1705 | if (barrier_cbs_tasks != NULL) { | 1259 | if (barrier_cbs_tasks != NULL) { |
1706 | for (i = 0; i < n_barrier_cbs; i++) { | 1260 | for (i = 0; i < n_barrier_cbs; i++) |
1707 | if (barrier_cbs_tasks[i] != NULL) { | 1261 | torture_stop_kthread(rcu_torture_barrier_cbs, |
1708 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_barrier_cbs task"); | 1262 | barrier_cbs_tasks[i]); |
1709 | kthread_stop(barrier_cbs_tasks[i]); | ||
1710 | barrier_cbs_tasks[i] = NULL; | ||
1711 | } | ||
1712 | } | ||
1713 | kfree(barrier_cbs_tasks); | 1263 | kfree(barrier_cbs_tasks); |
1714 | barrier_cbs_tasks = NULL; | 1264 | barrier_cbs_tasks = NULL; |
1715 | } | 1265 | } |
@@ -1747,90 +1297,42 @@ rcu_torture_cleanup(void) | |||
1747 | { | 1297 | { |
1748 | int i; | 1298 | int i; |
1749 | 1299 | ||
1750 | mutex_lock(&fullstop_mutex); | ||
1751 | rcutorture_record_test_transition(); | 1300 | rcutorture_record_test_transition(); |
1752 | if (fullstop == FULLSTOP_SHUTDOWN) { | 1301 | if (torture_cleanup()) { |
1753 | pr_warn(/* but going down anyway, so... */ | ||
1754 | "Concurrent 'rmmod rcutorture' and shutdown illegal!\n"); | ||
1755 | mutex_unlock(&fullstop_mutex); | ||
1756 | schedule_timeout_uninterruptible(10); | ||
1757 | if (cur_ops->cb_barrier != NULL) | 1302 | if (cur_ops->cb_barrier != NULL) |
1758 | cur_ops->cb_barrier(); | 1303 | cur_ops->cb_barrier(); |
1759 | return; | 1304 | return; |
1760 | } | 1305 | } |
1761 | fullstop = FULLSTOP_RMMOD; | ||
1762 | mutex_unlock(&fullstop_mutex); | ||
1763 | unregister_reboot_notifier(&rcutorture_shutdown_nb); | ||
1764 | rcu_torture_barrier_cleanup(); | ||
1765 | rcu_torture_stall_cleanup(); | ||
1766 | if (stutter_task) { | ||
1767 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_stutter task"); | ||
1768 | kthread_stop(stutter_task); | ||
1769 | } | ||
1770 | stutter_task = NULL; | ||
1771 | if (shuffler_task) { | ||
1772 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_shuffle task"); | ||
1773 | kthread_stop(shuffler_task); | ||
1774 | free_cpumask_var(shuffle_tmp_mask); | ||
1775 | } | ||
1776 | shuffler_task = NULL; | ||
1777 | 1306 | ||
1778 | if (writer_task) { | 1307 | rcu_torture_barrier_cleanup(); |
1779 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task"); | 1308 | torture_stop_kthread(rcu_torture_stall, stall_task); |
1780 | kthread_stop(writer_task); | 1309 | torture_stop_kthread(rcu_torture_writer, writer_task); |
1781 | } | ||
1782 | writer_task = NULL; | ||
1783 | 1310 | ||
1784 | if (reader_tasks) { | 1311 | if (reader_tasks) { |
1785 | for (i = 0; i < nrealreaders; i++) { | 1312 | for (i = 0; i < nrealreaders; i++) |
1786 | if (reader_tasks[i]) { | 1313 | torture_stop_kthread(rcu_torture_reader, |
1787 | VERBOSE_PRINTK_STRING( | 1314 | reader_tasks[i]); |
1788 | "Stopping rcu_torture_reader task"); | ||
1789 | kthread_stop(reader_tasks[i]); | ||
1790 | } | ||
1791 | reader_tasks[i] = NULL; | ||
1792 | } | ||
1793 | kfree(reader_tasks); | 1315 | kfree(reader_tasks); |
1794 | reader_tasks = NULL; | ||
1795 | } | 1316 | } |
1796 | rcu_torture_current = NULL; | 1317 | rcu_torture_current = NULL; |
1797 | 1318 | ||
1798 | if (fakewriter_tasks) { | 1319 | if (fakewriter_tasks) { |
1799 | for (i = 0; i < nfakewriters; i++) { | 1320 | for (i = 0; i < nfakewriters; i++) { |
1800 | if (fakewriter_tasks[i]) { | 1321 | torture_stop_kthread(rcu_torture_fakewriter, |
1801 | VERBOSE_PRINTK_STRING( | 1322 | fakewriter_tasks[i]); |
1802 | "Stopping rcu_torture_fakewriter task"); | ||
1803 | kthread_stop(fakewriter_tasks[i]); | ||
1804 | } | ||
1805 | fakewriter_tasks[i] = NULL; | ||
1806 | } | 1323 | } |
1807 | kfree(fakewriter_tasks); | 1324 | kfree(fakewriter_tasks); |
1808 | fakewriter_tasks = NULL; | 1325 | fakewriter_tasks = NULL; |
1809 | } | 1326 | } |
1810 | 1327 | ||
1811 | if (stats_task) { | 1328 | torture_stop_kthread(rcu_torture_stats, stats_task); |
1812 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task"); | 1329 | torture_stop_kthread(rcu_torture_fqs, fqs_task); |
1813 | kthread_stop(stats_task); | ||
1814 | } | ||
1815 | stats_task = NULL; | ||
1816 | |||
1817 | if (fqs_task) { | ||
1818 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_fqs task"); | ||
1819 | kthread_stop(fqs_task); | ||
1820 | } | ||
1821 | fqs_task = NULL; | ||
1822 | if ((test_boost == 1 && cur_ops->can_boost) || | 1330 | if ((test_boost == 1 && cur_ops->can_boost) || |
1823 | test_boost == 2) { | 1331 | test_boost == 2) { |
1824 | unregister_cpu_notifier(&rcutorture_cpu_nb); | 1332 | unregister_cpu_notifier(&rcutorture_cpu_nb); |
1825 | for_each_possible_cpu(i) | 1333 | for_each_possible_cpu(i) |
1826 | rcutorture_booster_cleanup(i); | 1334 | rcutorture_booster_cleanup(i); |
1827 | } | 1335 | } |
1828 | if (shutdown_task != NULL) { | ||
1829 | VERBOSE_PRINTK_STRING("Stopping rcu_torture_shutdown task"); | ||
1830 | kthread_stop(shutdown_task); | ||
1831 | } | ||
1832 | shutdown_task = NULL; | ||
1833 | rcu_torture_onoff_cleanup(); | ||
1834 | 1336 | ||
1835 | /* Wait for all RCU callbacks to fire. */ | 1337 | /* Wait for all RCU callbacks to fire. */ |
1836 | 1338 | ||
@@ -1841,8 +1343,7 @@ rcu_torture_cleanup(void) | |||
1841 | 1343 | ||
1842 | if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error) | 1344 | if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error) |
1843 | rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE"); | 1345 | rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE"); |
1844 | else if (n_online_successes != n_online_attempts || | 1346 | else if (torture_onoff_failures()) |
1845 | n_offline_successes != n_offline_attempts) | ||
1846 | rcu_torture_print_module_parms(cur_ops, | 1347 | rcu_torture_print_module_parms(cur_ops, |
1847 | "End of test: RCU_HOTPLUG"); | 1348 | "End of test: RCU_HOTPLUG"); |
1848 | else | 1349 | else |
@@ -1911,12 +1412,11 @@ rcu_torture_init(void) | |||
1911 | int i; | 1412 | int i; |
1912 | int cpu; | 1413 | int cpu; |
1913 | int firsterr = 0; | 1414 | int firsterr = 0; |
1914 | int retval; | ||
1915 | static struct rcu_torture_ops *torture_ops[] = { | 1415 | static struct rcu_torture_ops *torture_ops[] = { |
1916 | &rcu_ops, &rcu_bh_ops, &srcu_ops, &sched_ops, | 1416 | &rcu_ops, &rcu_bh_ops, &rcu_busted_ops, &srcu_ops, &sched_ops, |
1917 | }; | 1417 | }; |
1918 | 1418 | ||
1919 | mutex_lock(&fullstop_mutex); | 1419 | torture_init_begin(torture_type, verbose, &rcutorture_runnable); |
1920 | 1420 | ||
1921 | /* Process args and tell the world that the torturer is on the job. */ | 1421 | /* Process args and tell the world that the torturer is on the job. */ |
1922 | for (i = 0; i < ARRAY_SIZE(torture_ops); i++) { | 1422 | for (i = 0; i < ARRAY_SIZE(torture_ops); i++) { |
@@ -1931,7 +1431,7 @@ rcu_torture_init(void) | |||
1931 | for (i = 0; i < ARRAY_SIZE(torture_ops); i++) | 1431 | for (i = 0; i < ARRAY_SIZE(torture_ops); i++) |
1932 | pr_alert(" %s", torture_ops[i]->name); | 1432 | pr_alert(" %s", torture_ops[i]->name); |
1933 | pr_alert("\n"); | 1433 | pr_alert("\n"); |
1934 | mutex_unlock(&fullstop_mutex); | 1434 | torture_init_end(); |
1935 | return -EINVAL; | 1435 | return -EINVAL; |
1936 | } | 1436 | } |
1937 | if (cur_ops->fqs == NULL && fqs_duration != 0) { | 1437 | if (cur_ops->fqs == NULL && fqs_duration != 0) { |
@@ -1946,7 +1446,6 @@ rcu_torture_init(void) | |||
1946 | else | 1446 | else |
1947 | nrealreaders = 2 * num_online_cpus(); | 1447 | nrealreaders = 2 * num_online_cpus(); |
1948 | rcu_torture_print_module_parms(cur_ops, "Start of test"); | 1448 | rcu_torture_print_module_parms(cur_ops, "Start of test"); |
1949 | fullstop = FULLSTOP_DONTSTOP; | ||
1950 | 1449 | ||
1951 | /* Set up the freelist. */ | 1450 | /* Set up the freelist. */ |
1952 | 1451 | ||
@@ -1982,108 +1481,61 @@ rcu_torture_init(void) | |||
1982 | 1481 | ||
1983 | /* Start up the kthreads. */ | 1482 | /* Start up the kthreads. */ |
1984 | 1483 | ||
1985 | VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task"); | 1484 | firsterr = torture_create_kthread(rcu_torture_writer, NULL, |
1986 | writer_task = kthread_create(rcu_torture_writer, NULL, | 1485 | writer_task); |
1987 | "rcu_torture_writer"); | 1486 | if (firsterr) |
1988 | if (IS_ERR(writer_task)) { | ||
1989 | firsterr = PTR_ERR(writer_task); | ||
1990 | VERBOSE_PRINTK_ERRSTRING("Failed to create writer"); | ||
1991 | writer_task = NULL; | ||
1992 | goto unwind; | 1487 | goto unwind; |
1993 | } | ||
1994 | wake_up_process(writer_task); | ||
1995 | fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), | 1488 | fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), |
1996 | GFP_KERNEL); | 1489 | GFP_KERNEL); |
1997 | if (fakewriter_tasks == NULL) { | 1490 | if (fakewriter_tasks == NULL) { |
1998 | VERBOSE_PRINTK_ERRSTRING("out of memory"); | 1491 | VERBOSE_TOROUT_ERRSTRING("out of memory"); |
1999 | firsterr = -ENOMEM; | 1492 | firsterr = -ENOMEM; |
2000 | goto unwind; | 1493 | goto unwind; |
2001 | } | 1494 | } |
2002 | for (i = 0; i < nfakewriters; i++) { | 1495 | for (i = 0; i < nfakewriters; i++) { |
2003 | VERBOSE_PRINTK_STRING("Creating rcu_torture_fakewriter task"); | 1496 | firsterr = torture_create_kthread(rcu_torture_fakewriter, |
2004 | fakewriter_tasks[i] = kthread_run(rcu_torture_fakewriter, NULL, | 1497 | NULL, fakewriter_tasks[i]); |
2005 | "rcu_torture_fakewriter"); | 1498 | if (firsterr) |
2006 | if (IS_ERR(fakewriter_tasks[i])) { | ||
2007 | firsterr = PTR_ERR(fakewriter_tasks[i]); | ||
2008 | VERBOSE_PRINTK_ERRSTRING("Failed to create fakewriter"); | ||
2009 | fakewriter_tasks[i] = NULL; | ||
2010 | goto unwind; | 1499 | goto unwind; |
2011 | } | ||
2012 | } | 1500 | } |
2013 | reader_tasks = kzalloc(nrealreaders * sizeof(reader_tasks[0]), | 1501 | reader_tasks = kzalloc(nrealreaders * sizeof(reader_tasks[0]), |
2014 | GFP_KERNEL); | 1502 | GFP_KERNEL); |
2015 | if (reader_tasks == NULL) { | 1503 | if (reader_tasks == NULL) { |
2016 | VERBOSE_PRINTK_ERRSTRING("out of memory"); | 1504 | VERBOSE_TOROUT_ERRSTRING("out of memory"); |
2017 | firsterr = -ENOMEM; | 1505 | firsterr = -ENOMEM; |
2018 | goto unwind; | 1506 | goto unwind; |
2019 | } | 1507 | } |
2020 | for (i = 0; i < nrealreaders; i++) { | 1508 | for (i = 0; i < nrealreaders; i++) { |
2021 | VERBOSE_PRINTK_STRING("Creating rcu_torture_reader task"); | 1509 | firsterr = torture_create_kthread(rcu_torture_reader, NULL, |
2022 | reader_tasks[i] = kthread_run(rcu_torture_reader, NULL, | 1510 | reader_tasks[i]); |
2023 | "rcu_torture_reader"); | 1511 | if (firsterr) |
2024 | if (IS_ERR(reader_tasks[i])) { | ||
2025 | firsterr = PTR_ERR(reader_tasks[i]); | ||
2026 | VERBOSE_PRINTK_ERRSTRING("Failed to create reader"); | ||
2027 | reader_tasks[i] = NULL; | ||
2028 | goto unwind; | 1512 | goto unwind; |
2029 | } | ||
2030 | } | 1513 | } |
2031 | if (stat_interval > 0) { | 1514 | if (stat_interval > 0) { |
2032 | VERBOSE_PRINTK_STRING("Creating rcu_torture_stats task"); | 1515 | firsterr = torture_create_kthread(rcu_torture_stats, NULL, |
2033 | stats_task = kthread_run(rcu_torture_stats, NULL, | 1516 | stats_task); |
2034 | "rcu_torture_stats"); | 1517 | if (firsterr) |
2035 | if (IS_ERR(stats_task)) { | ||
2036 | firsterr = PTR_ERR(stats_task); | ||
2037 | VERBOSE_PRINTK_ERRSTRING("Failed to create stats"); | ||
2038 | stats_task = NULL; | ||
2039 | goto unwind; | 1518 | goto unwind; |
2040 | } | ||
2041 | } | 1519 | } |
2042 | if (test_no_idle_hz) { | 1520 | if (test_no_idle_hz) { |
2043 | rcu_idle_cpu = num_online_cpus() - 1; | 1521 | firsterr = torture_shuffle_init(shuffle_interval * HZ); |
2044 | 1522 | if (firsterr) | |
2045 | if (!alloc_cpumask_var(&shuffle_tmp_mask, GFP_KERNEL)) { | ||
2046 | firsterr = -ENOMEM; | ||
2047 | VERBOSE_PRINTK_ERRSTRING("Failed to alloc mask"); | ||
2048 | goto unwind; | ||
2049 | } | ||
2050 | |||
2051 | /* Create the shuffler thread */ | ||
2052 | shuffler_task = kthread_run(rcu_torture_shuffle, NULL, | ||
2053 | "rcu_torture_shuffle"); | ||
2054 | if (IS_ERR(shuffler_task)) { | ||
2055 | free_cpumask_var(shuffle_tmp_mask); | ||
2056 | firsterr = PTR_ERR(shuffler_task); | ||
2057 | VERBOSE_PRINTK_ERRSTRING("Failed to create shuffler"); | ||
2058 | shuffler_task = NULL; | ||
2059 | goto unwind; | 1523 | goto unwind; |
2060 | } | ||
2061 | } | 1524 | } |
2062 | if (stutter < 0) | 1525 | if (stutter < 0) |
2063 | stutter = 0; | 1526 | stutter = 0; |
2064 | if (stutter) { | 1527 | if (stutter) { |
2065 | /* Create the stutter thread */ | 1528 | firsterr = torture_stutter_init(stutter * HZ); |
2066 | stutter_task = kthread_run(rcu_torture_stutter, NULL, | 1529 | if (firsterr) |
2067 | "rcu_torture_stutter"); | ||
2068 | if (IS_ERR(stutter_task)) { | ||
2069 | firsterr = PTR_ERR(stutter_task); | ||
2070 | VERBOSE_PRINTK_ERRSTRING("Failed to create stutter"); | ||
2071 | stutter_task = NULL; | ||
2072 | goto unwind; | 1530 | goto unwind; |
2073 | } | ||
2074 | } | 1531 | } |
2075 | if (fqs_duration < 0) | 1532 | if (fqs_duration < 0) |
2076 | fqs_duration = 0; | 1533 | fqs_duration = 0; |
2077 | if (fqs_duration) { | 1534 | if (fqs_duration) { |
2078 | /* Create the stutter thread */ | 1535 | /* Create the fqs thread */ |
2079 | fqs_task = kthread_run(rcu_torture_fqs, NULL, | 1536 | torture_create_kthread(rcu_torture_fqs, NULL, fqs_task); |
2080 | "rcu_torture_fqs"); | 1537 | if (firsterr) |
2081 | if (IS_ERR(fqs_task)) { | ||
2082 | firsterr = PTR_ERR(fqs_task); | ||
2083 | VERBOSE_PRINTK_ERRSTRING("Failed to create fqs"); | ||
2084 | fqs_task = NULL; | ||
2085 | goto unwind; | 1538 | goto unwind; |
2086 | } | ||
2087 | } | 1539 | } |
2088 | if (test_boost_interval < 1) | 1540 | if (test_boost_interval < 1) |
2089 | test_boost_interval = 1; | 1541 | test_boost_interval = 1; |
@@ -2097,49 +1549,31 @@ rcu_torture_init(void) | |||
2097 | for_each_possible_cpu(i) { | 1549 | for_each_possible_cpu(i) { |
2098 | if (cpu_is_offline(i)) | 1550 | if (cpu_is_offline(i)) |
2099 | continue; /* Heuristic: CPU can go offline. */ | 1551 | continue; /* Heuristic: CPU can go offline. */ |
2100 | retval = rcutorture_booster_init(i); | 1552 | firsterr = rcutorture_booster_init(i); |
2101 | if (retval < 0) { | 1553 | if (firsterr) |
2102 | firsterr = retval; | ||
2103 | goto unwind; | 1554 | goto unwind; |
2104 | } | ||
2105 | } | 1555 | } |
2106 | } | 1556 | } |
2107 | if (shutdown_secs > 0) { | 1557 | firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup); |
2108 | shutdown_time = jiffies + shutdown_secs * HZ; | 1558 | if (firsterr) |
2109 | shutdown_task = kthread_create(rcu_torture_shutdown, NULL, | ||
2110 | "rcu_torture_shutdown"); | ||
2111 | if (IS_ERR(shutdown_task)) { | ||
2112 | firsterr = PTR_ERR(shutdown_task); | ||
2113 | VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown"); | ||
2114 | shutdown_task = NULL; | ||
2115 | goto unwind; | ||
2116 | } | ||
2117 | wake_up_process(shutdown_task); | ||
2118 | } | ||
2119 | i = rcu_torture_onoff_init(); | ||
2120 | if (i != 0) { | ||
2121 | firsterr = i; | ||
2122 | goto unwind; | 1559 | goto unwind; |
2123 | } | 1560 | firsterr = torture_onoff_init(onoff_holdoff * HZ, onoff_interval * HZ); |
2124 | register_reboot_notifier(&rcutorture_shutdown_nb); | 1561 | if (firsterr) |
2125 | i = rcu_torture_stall_init(); | ||
2126 | if (i != 0) { | ||
2127 | firsterr = i; | ||
2128 | goto unwind; | 1562 | goto unwind; |
2129 | } | 1563 | firsterr = rcu_torture_stall_init(); |
2130 | retval = rcu_torture_barrier_init(); | 1564 | if (firsterr) |
2131 | if (retval != 0) { | 1565 | goto unwind; |
2132 | firsterr = retval; | 1566 | firsterr = rcu_torture_barrier_init(); |
1567 | if (firsterr) | ||
2133 | goto unwind; | 1568 | goto unwind; |
2134 | } | ||
2135 | if (object_debug) | 1569 | if (object_debug) |
2136 | rcu_test_debug_objects(); | 1570 | rcu_test_debug_objects(); |
2137 | rcutorture_record_test_transition(); | 1571 | rcutorture_record_test_transition(); |
2138 | mutex_unlock(&fullstop_mutex); | 1572 | torture_init_end(); |
2139 | return 0; | 1573 | return 0; |
2140 | 1574 | ||
2141 | unwind: | 1575 | unwind: |
2142 | mutex_unlock(&fullstop_mutex); | 1576 | torture_init_end(); |
2143 | rcu_torture_cleanup(); | 1577 | rcu_torture_cleanup(); |
2144 | return firsterr; | 1578 | return firsterr; |
2145 | } | 1579 | } |
diff --git a/kernel/torture.c b/kernel/torture.c new file mode 100644 index 000000000000..acc9afc2f26e --- /dev/null +++ b/kernel/torture.c | |||
@@ -0,0 +1,719 @@ | |||
1 | /* | ||
2 | * Common functions for in-kernel torture tests. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, you can access it online at | ||
16 | * http://www.gnu.org/licenses/gpl-2.0.html. | ||
17 | * | ||
18 | * Copyright (C) IBM Corporation, 2014 | ||
19 | * | ||
20 | * Author: Paul E. McKenney <paulmck@us.ibm.com> | ||
21 | * Based on kernel/rcu/torture.c. | ||
22 | */ | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/kthread.h> | ||
28 | #include <linux/err.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/smp.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/sched.h> | ||
33 | #include <linux/atomic.h> | ||
34 | #include <linux/bitops.h> | ||
35 | #include <linux/completion.h> | ||
36 | #include <linux/moduleparam.h> | ||
37 | #include <linux/percpu.h> | ||
38 | #include <linux/notifier.h> | ||
39 | #include <linux/reboot.h> | ||
40 | #include <linux/freezer.h> | ||
41 | #include <linux/cpu.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/stat.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <linux/trace_clock.h> | ||
46 | #include <asm/byteorder.h> | ||
47 | #include <linux/torture.h> | ||
48 | |||
49 | MODULE_LICENSE("GPL"); | ||
50 | MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com>"); | ||
51 | |||
52 | static char *torture_type; | ||
53 | static bool verbose; | ||
54 | |||
55 | /* Mediate rmmod and system shutdown. Concurrent rmmod & shutdown illegal! */ | ||
56 | #define FULLSTOP_DONTSTOP 0 /* Normal operation. */ | ||
57 | #define FULLSTOP_SHUTDOWN 1 /* System shutdown with torture running. */ | ||
58 | #define FULLSTOP_RMMOD 2 /* Normal rmmod of torture. */ | ||
59 | static int fullstop = FULLSTOP_RMMOD; | ||
60 | static DEFINE_MUTEX(fullstop_mutex); | ||
61 | static int *torture_runnable; | ||
62 | |||
63 | #ifdef CONFIG_HOTPLUG_CPU | ||
64 | |||
65 | /* | ||
66 | * Variables for online-offline handling. Only present if CPU hotplug | ||
67 | * is enabled, otherwise does nothing. | ||
68 | */ | ||
69 | |||
70 | static struct task_struct *onoff_task; | ||
71 | static long onoff_holdoff; | ||
72 | static long onoff_interval; | ||
73 | static long n_offline_attempts; | ||
74 | static long n_offline_successes; | ||
75 | static unsigned long sum_offline; | ||
76 | static int min_offline = -1; | ||
77 | static int max_offline; | ||
78 | static long n_online_attempts; | ||
79 | static long n_online_successes; | ||
80 | static unsigned long sum_online; | ||
81 | static int min_online = -1; | ||
82 | static int max_online; | ||
83 | |||
84 | /* | ||
85 | * Execute random CPU-hotplug operations at the interval specified | ||
86 | * by the onoff_interval. | ||
87 | */ | ||
88 | static int | ||
89 | torture_onoff(void *arg) | ||
90 | { | ||
91 | int cpu; | ||
92 | unsigned long delta; | ||
93 | int maxcpu = -1; | ||
94 | DEFINE_TORTURE_RANDOM(rand); | ||
95 | int ret; | ||
96 | unsigned long starttime; | ||
97 | |||
98 | VERBOSE_TOROUT_STRING("torture_onoff task started"); | ||
99 | for_each_online_cpu(cpu) | ||
100 | maxcpu = cpu; | ||
101 | WARN_ON(maxcpu < 0); | ||
102 | if (onoff_holdoff > 0) { | ||
103 | VERBOSE_TOROUT_STRING("torture_onoff begin holdoff"); | ||
104 | schedule_timeout_interruptible(onoff_holdoff); | ||
105 | VERBOSE_TOROUT_STRING("torture_onoff end holdoff"); | ||
106 | } | ||
107 | while (!torture_must_stop()) { | ||
108 | cpu = (torture_random(&rand) >> 4) % (maxcpu + 1); | ||
109 | if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) { | ||
110 | if (verbose) | ||
111 | pr_alert("%s" TORTURE_FLAG | ||
112 | "torture_onoff task: offlining %d\n", | ||
113 | torture_type, cpu); | ||
114 | starttime = jiffies; | ||
115 | n_offline_attempts++; | ||
116 | ret = cpu_down(cpu); | ||
117 | if (ret) { | ||
118 | if (verbose) | ||
119 | pr_alert("%s" TORTURE_FLAG | ||
120 | "torture_onoff task: offline %d failed: errno %d\n", | ||
121 | torture_type, cpu, ret); | ||
122 | } else { | ||
123 | if (verbose) | ||
124 | pr_alert("%s" TORTURE_FLAG | ||
125 | "torture_onoff task: offlined %d\n", | ||
126 | torture_type, cpu); | ||
127 | n_offline_successes++; | ||
128 | delta = jiffies - starttime; | ||
129 | sum_offline += delta; | ||
130 | if (min_offline < 0) { | ||
131 | min_offline = delta; | ||
132 | max_offline = delta; | ||
133 | } | ||
134 | if (min_offline > delta) | ||
135 | min_offline = delta; | ||
136 | if (max_offline < delta) | ||
137 | max_offline = delta; | ||
138 | } | ||
139 | } else if (cpu_is_hotpluggable(cpu)) { | ||
140 | if (verbose) | ||
141 | pr_alert("%s" TORTURE_FLAG | ||
142 | "torture_onoff task: onlining %d\n", | ||
143 | torture_type, cpu); | ||
144 | starttime = jiffies; | ||
145 | n_online_attempts++; | ||
146 | ret = cpu_up(cpu); | ||
147 | if (ret) { | ||
148 | if (verbose) | ||
149 | pr_alert("%s" TORTURE_FLAG | ||
150 | "torture_onoff task: online %d failed: errno %d\n", | ||
151 | torture_type, cpu, ret); | ||
152 | } else { | ||
153 | if (verbose) | ||
154 | pr_alert("%s" TORTURE_FLAG | ||
155 | "torture_onoff task: onlined %d\n", | ||
156 | torture_type, cpu); | ||
157 | n_online_successes++; | ||
158 | delta = jiffies - starttime; | ||
159 | sum_online += delta; | ||
160 | if (min_online < 0) { | ||
161 | min_online = delta; | ||
162 | max_online = delta; | ||
163 | } | ||
164 | if (min_online > delta) | ||
165 | min_online = delta; | ||
166 | if (max_online < delta) | ||
167 | max_online = delta; | ||
168 | } | ||
169 | } | ||
170 | schedule_timeout_interruptible(onoff_interval); | ||
171 | } | ||
172 | torture_kthread_stopping("torture_onoff"); | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | ||
177 | |||
178 | /* | ||
179 | * Initiate online-offline handling. | ||
180 | */ | ||
181 | int torture_onoff_init(long ooholdoff, long oointerval) | ||
182 | { | ||
183 | int ret = 0; | ||
184 | |||
185 | #ifdef CONFIG_HOTPLUG_CPU | ||
186 | onoff_holdoff = ooholdoff; | ||
187 | onoff_interval = oointerval; | ||
188 | if (onoff_interval <= 0) | ||
189 | return 0; | ||
190 | ret = torture_create_kthread(torture_onoff, NULL, onoff_task); | ||
191 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | ||
192 | return ret; | ||
193 | } | ||
194 | EXPORT_SYMBOL_GPL(torture_onoff_init); | ||
195 | |||
196 | /* | ||
197 | * Clean up after online/offline testing. | ||
198 | */ | ||
199 | static void torture_onoff_cleanup(void) | ||
200 | { | ||
201 | #ifdef CONFIG_HOTPLUG_CPU | ||
202 | if (onoff_task == NULL) | ||
203 | return; | ||
204 | VERBOSE_TOROUT_STRING("Stopping torture_onoff task"); | ||
205 | kthread_stop(onoff_task); | ||
206 | onoff_task = NULL; | ||
207 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | ||
208 | } | ||
209 | EXPORT_SYMBOL_GPL(torture_onoff_cleanup); | ||
210 | |||
211 | /* | ||
212 | * Print online/offline testing statistics. | ||
213 | */ | ||
214 | char *torture_onoff_stats(char *page) | ||
215 | { | ||
216 | #ifdef CONFIG_HOTPLUG_CPU | ||
217 | page += sprintf(page, | ||
218 | "onoff: %ld/%ld:%ld/%ld %d,%d:%d,%d %lu:%lu (HZ=%d) ", | ||
219 | n_online_successes, n_online_attempts, | ||
220 | n_offline_successes, n_offline_attempts, | ||
221 | min_online, max_online, | ||
222 | min_offline, max_offline, | ||
223 | sum_online, sum_offline, HZ); | ||
224 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | ||
225 | return page; | ||
226 | } | ||
227 | EXPORT_SYMBOL_GPL(torture_onoff_stats); | ||
228 | |||
229 | /* | ||
230 | * Were all the online/offline operations successful? | ||
231 | */ | ||
232 | bool torture_onoff_failures(void) | ||
233 | { | ||
234 | #ifdef CONFIG_HOTPLUG_CPU | ||
235 | return n_online_successes != n_online_attempts || | ||
236 | n_offline_successes != n_offline_attempts; | ||
237 | #else /* #ifdef CONFIG_HOTPLUG_CPU */ | ||
238 | return false; | ||
239 | #endif /* #else #ifdef CONFIG_HOTPLUG_CPU */ | ||
240 | } | ||
241 | EXPORT_SYMBOL_GPL(torture_onoff_failures); | ||
242 | |||
243 | #define TORTURE_RANDOM_MULT 39916801 /* prime */ | ||
244 | #define TORTURE_RANDOM_ADD 479001701 /* prime */ | ||
245 | #define TORTURE_RANDOM_REFRESH 10000 | ||
246 | |||
247 | /* | ||
248 | * Crude but fast random-number generator. Uses a linear congruential | ||
249 | * generator, with occasional help from cpu_clock(). | ||
250 | */ | ||
251 | unsigned long | ||
252 | torture_random(struct torture_random_state *trsp) | ||
253 | { | ||
254 | if (--trsp->trs_count < 0) { | ||
255 | trsp->trs_state += (unsigned long)local_clock(); | ||
256 | trsp->trs_count = TORTURE_RANDOM_REFRESH; | ||
257 | } | ||
258 | trsp->trs_state = trsp->trs_state * TORTURE_RANDOM_MULT + | ||
259 | TORTURE_RANDOM_ADD; | ||
260 | return swahw32(trsp->trs_state); | ||
261 | } | ||
262 | EXPORT_SYMBOL_GPL(torture_random); | ||
263 | |||
264 | /* | ||
265 | * Variables for shuffling. The idea is to ensure that each CPU stays | ||
266 | * idle for an extended period to test interactions with dyntick idle, | ||
267 | * as well as interactions with any per-CPU varibles. | ||
268 | */ | ||
269 | struct shuffle_task { | ||
270 | struct list_head st_l; | ||
271 | struct task_struct *st_t; | ||
272 | }; | ||
273 | |||
274 | static long shuffle_interval; /* In jiffies. */ | ||
275 | static struct task_struct *shuffler_task; | ||
276 | static cpumask_var_t shuffle_tmp_mask; | ||
277 | static int shuffle_idle_cpu; /* Force all torture tasks off this CPU */ | ||
278 | static struct list_head shuffle_task_list = LIST_HEAD_INIT(shuffle_task_list); | ||
279 | static DEFINE_MUTEX(shuffle_task_mutex); | ||
280 | |||
281 | /* | ||
282 | * Register a task to be shuffled. If there is no memory, just splat | ||
283 | * and don't bother registering. | ||
284 | */ | ||
285 | void torture_shuffle_task_register(struct task_struct *tp) | ||
286 | { | ||
287 | struct shuffle_task *stp; | ||
288 | |||
289 | if (WARN_ON_ONCE(tp == NULL)) | ||
290 | return; | ||
291 | stp = kmalloc(sizeof(*stp), GFP_KERNEL); | ||
292 | if (WARN_ON_ONCE(stp == NULL)) | ||
293 | return; | ||
294 | stp->st_t = tp; | ||
295 | mutex_lock(&shuffle_task_mutex); | ||
296 | list_add(&stp->st_l, &shuffle_task_list); | ||
297 | mutex_unlock(&shuffle_task_mutex); | ||
298 | } | ||
299 | EXPORT_SYMBOL_GPL(torture_shuffle_task_register); | ||
300 | |||
301 | /* | ||
302 | * Unregister all tasks, for example, at the end of the torture run. | ||
303 | */ | ||
304 | static void torture_shuffle_task_unregister_all(void) | ||
305 | { | ||
306 | struct shuffle_task *stp; | ||
307 | struct shuffle_task *p; | ||
308 | |||
309 | mutex_lock(&shuffle_task_mutex); | ||
310 | list_for_each_entry_safe(stp, p, &shuffle_task_list, st_l) { | ||
311 | list_del(&stp->st_l); | ||
312 | kfree(stp); | ||
313 | } | ||
314 | mutex_unlock(&shuffle_task_mutex); | ||
315 | } | ||
316 | |||
317 | /* Shuffle tasks such that we allow shuffle_idle_cpu to become idle. | ||
318 | * A special case is when shuffle_idle_cpu = -1, in which case we allow | ||
319 | * the tasks to run on all CPUs. | ||
320 | */ | ||
321 | static void torture_shuffle_tasks(void) | ||
322 | { | ||
323 | struct shuffle_task *stp; | ||
324 | |||
325 | cpumask_setall(shuffle_tmp_mask); | ||
326 | get_online_cpus(); | ||
327 | |||
328 | /* No point in shuffling if there is only one online CPU (ex: UP) */ | ||
329 | if (num_online_cpus() == 1) { | ||
330 | put_online_cpus(); | ||
331 | return; | ||
332 | } | ||
333 | |||
334 | /* Advance to the next CPU. Upon overflow, don't idle any CPUs. */ | ||
335 | shuffle_idle_cpu = cpumask_next(shuffle_idle_cpu, shuffle_tmp_mask); | ||
336 | if (shuffle_idle_cpu >= nr_cpu_ids) | ||
337 | shuffle_idle_cpu = -1; | ||
338 | if (shuffle_idle_cpu != -1) { | ||
339 | cpumask_clear_cpu(shuffle_idle_cpu, shuffle_tmp_mask); | ||
340 | if (cpumask_empty(shuffle_tmp_mask)) { | ||
341 | put_online_cpus(); | ||
342 | return; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | mutex_lock(&shuffle_task_mutex); | ||
347 | list_for_each_entry(stp, &shuffle_task_list, st_l) | ||
348 | set_cpus_allowed_ptr(stp->st_t, shuffle_tmp_mask); | ||
349 | mutex_unlock(&shuffle_task_mutex); | ||
350 | |||
351 | put_online_cpus(); | ||
352 | } | ||
353 | |||
354 | /* Shuffle tasks across CPUs, with the intent of allowing each CPU in the | ||
355 | * system to become idle at a time and cut off its timer ticks. This is meant | ||
356 | * to test the support for such tickless idle CPU in RCU. | ||
357 | */ | ||
358 | static int torture_shuffle(void *arg) | ||
359 | { | ||
360 | VERBOSE_TOROUT_STRING("torture_shuffle task started"); | ||
361 | do { | ||
362 | schedule_timeout_interruptible(shuffle_interval); | ||
363 | torture_shuffle_tasks(); | ||
364 | torture_shutdown_absorb("torture_shuffle"); | ||
365 | } while (!torture_must_stop()); | ||
366 | torture_kthread_stopping("torture_shuffle"); | ||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | /* | ||
371 | * Start the shuffler, with shuffint in jiffies. | ||
372 | */ | ||
373 | int torture_shuffle_init(long shuffint) | ||
374 | { | ||
375 | shuffle_interval = shuffint; | ||
376 | |||
377 | shuffle_idle_cpu = -1; | ||
378 | |||
379 | if (!alloc_cpumask_var(&shuffle_tmp_mask, GFP_KERNEL)) { | ||
380 | VERBOSE_TOROUT_ERRSTRING("Failed to alloc mask"); | ||
381 | return -ENOMEM; | ||
382 | } | ||
383 | |||
384 | /* Create the shuffler thread */ | ||
385 | return torture_create_kthread(torture_shuffle, NULL, shuffler_task); | ||
386 | } | ||
387 | EXPORT_SYMBOL_GPL(torture_shuffle_init); | ||
388 | |||
389 | /* | ||
390 | * Stop the shuffling. | ||
391 | */ | ||
392 | static void torture_shuffle_cleanup(void) | ||
393 | { | ||
394 | torture_shuffle_task_unregister_all(); | ||
395 | if (shuffler_task) { | ||
396 | VERBOSE_TOROUT_STRING("Stopping torture_shuffle task"); | ||
397 | kthread_stop(shuffler_task); | ||
398 | free_cpumask_var(shuffle_tmp_mask); | ||
399 | } | ||
400 | shuffler_task = NULL; | ||
401 | } | ||
402 | EXPORT_SYMBOL_GPL(torture_shuffle_cleanup); | ||
403 | |||
404 | /* | ||
405 | * Variables for auto-shutdown. This allows "lights out" torture runs | ||
406 | * to be fully scripted. | ||
407 | */ | ||
408 | static int shutdown_secs; /* desired test duration in seconds. */ | ||
409 | static struct task_struct *shutdown_task; | ||
410 | static unsigned long shutdown_time; /* jiffies to system shutdown. */ | ||
411 | static void (*torture_shutdown_hook)(void); | ||
412 | |||
413 | /* | ||
414 | * Absorb kthreads into a kernel function that won't return, so that | ||
415 | * they won't ever access module text or data again. | ||
416 | */ | ||
417 | void torture_shutdown_absorb(const char *title) | ||
418 | { | ||
419 | while (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) { | ||
420 | pr_notice("torture thread %s parking due to system shutdown\n", | ||
421 | title); | ||
422 | schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT); | ||
423 | } | ||
424 | } | ||
425 | EXPORT_SYMBOL_GPL(torture_shutdown_absorb); | ||
426 | |||
427 | /* | ||
428 | * Cause the torture test to shutdown the system after the test has | ||
429 | * run for the time specified by the shutdown_secs parameter. | ||
430 | */ | ||
431 | static int torture_shutdown(void *arg) | ||
432 | { | ||
433 | long delta; | ||
434 | unsigned long jiffies_snap; | ||
435 | |||
436 | VERBOSE_TOROUT_STRING("torture_shutdown task started"); | ||
437 | jiffies_snap = jiffies; | ||
438 | while (ULONG_CMP_LT(jiffies_snap, shutdown_time) && | ||
439 | !torture_must_stop()) { | ||
440 | delta = shutdown_time - jiffies_snap; | ||
441 | if (verbose) | ||
442 | pr_alert("%s" TORTURE_FLAG | ||
443 | "torture_shutdown task: %lu jiffies remaining\n", | ||
444 | torture_type, delta); | ||
445 | schedule_timeout_interruptible(delta); | ||
446 | jiffies_snap = jiffies; | ||
447 | } | ||
448 | if (torture_must_stop()) { | ||
449 | torture_kthread_stopping("torture_shutdown"); | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | /* OK, shut down the system. */ | ||
454 | |||
455 | VERBOSE_TOROUT_STRING("torture_shutdown task shutting down system"); | ||
456 | shutdown_task = NULL; /* Avoid self-kill deadlock. */ | ||
457 | if (torture_shutdown_hook) | ||
458 | torture_shutdown_hook(); | ||
459 | else | ||
460 | VERBOSE_TOROUT_STRING("No torture_shutdown_hook(), skipping."); | ||
461 | kernel_power_off(); /* Shut down the system. */ | ||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | /* | ||
466 | * Start up the shutdown task. | ||
467 | */ | ||
468 | int torture_shutdown_init(int ssecs, void (*cleanup)(void)) | ||
469 | { | ||
470 | int ret = 0; | ||
471 | |||
472 | shutdown_secs = ssecs; | ||
473 | torture_shutdown_hook = cleanup; | ||
474 | if (shutdown_secs > 0) { | ||
475 | shutdown_time = jiffies + shutdown_secs * HZ; | ||
476 | ret = torture_create_kthread(torture_shutdown, NULL, | ||
477 | shutdown_task); | ||
478 | } | ||
479 | return ret; | ||
480 | } | ||
481 | EXPORT_SYMBOL_GPL(torture_shutdown_init); | ||
482 | |||
483 | /* | ||
484 | * Detect and respond to a system shutdown. | ||
485 | */ | ||
486 | static int torture_shutdown_notify(struct notifier_block *unused1, | ||
487 | unsigned long unused2, void *unused3) | ||
488 | { | ||
489 | mutex_lock(&fullstop_mutex); | ||
490 | if (ACCESS_ONCE(fullstop) == FULLSTOP_DONTSTOP) { | ||
491 | VERBOSE_TOROUT_STRING("Unscheduled system shutdown detected"); | ||
492 | ACCESS_ONCE(fullstop) = FULLSTOP_SHUTDOWN; | ||
493 | } else { | ||
494 | pr_warn("Concurrent rmmod and shutdown illegal!\n"); | ||
495 | } | ||
496 | mutex_unlock(&fullstop_mutex); | ||
497 | return NOTIFY_DONE; | ||
498 | } | ||
499 | |||
500 | static struct notifier_block torture_shutdown_nb = { | ||
501 | .notifier_call = torture_shutdown_notify, | ||
502 | }; | ||
503 | |||
504 | /* | ||
505 | * Shut down the shutdown task. Say what??? Heh! This can happen if | ||
506 | * the torture module gets an rmmod before the shutdown time arrives. ;-) | ||
507 | */ | ||
508 | static void torture_shutdown_cleanup(void) | ||
509 | { | ||
510 | unregister_reboot_notifier(&torture_shutdown_nb); | ||
511 | if (shutdown_task != NULL) { | ||
512 | VERBOSE_TOROUT_STRING("Stopping torture_shutdown task"); | ||
513 | kthread_stop(shutdown_task); | ||
514 | } | ||
515 | shutdown_task = NULL; | ||
516 | } | ||
517 | |||
518 | /* | ||
519 | * Variables for stuttering, which means to periodically pause and | ||
520 | * restart testing in order to catch bugs that appear when load is | ||
521 | * suddenly applied to or removed from the system. | ||
522 | */ | ||
523 | static struct task_struct *stutter_task; | ||
524 | static int stutter_pause_test; | ||
525 | static int stutter; | ||
526 | |||
527 | /* | ||
528 | * Block until the stutter interval ends. This must be called periodically | ||
529 | * by all running kthreads that need to be subject to stuttering. | ||
530 | */ | ||
531 | void stutter_wait(const char *title) | ||
532 | { | ||
533 | while (ACCESS_ONCE(stutter_pause_test) || | ||
534 | (torture_runnable && !ACCESS_ONCE(*torture_runnable))) { | ||
535 | if (stutter_pause_test) | ||
536 | schedule_timeout_interruptible(1); | ||
537 | else | ||
538 | schedule_timeout_interruptible(round_jiffies_relative(HZ)); | ||
539 | torture_shutdown_absorb(title); | ||
540 | } | ||
541 | } | ||
542 | EXPORT_SYMBOL_GPL(stutter_wait); | ||
543 | |||
544 | /* | ||
545 | * Cause the torture test to "stutter", starting and stopping all | ||
546 | * threads periodically. | ||
547 | */ | ||
548 | static int torture_stutter(void *arg) | ||
549 | { | ||
550 | VERBOSE_TOROUT_STRING("torture_stutter task started"); | ||
551 | do { | ||
552 | if (!torture_must_stop()) { | ||
553 | schedule_timeout_interruptible(stutter); | ||
554 | ACCESS_ONCE(stutter_pause_test) = 1; | ||
555 | } | ||
556 | if (!torture_must_stop()) | ||
557 | schedule_timeout_interruptible(stutter); | ||
558 | ACCESS_ONCE(stutter_pause_test) = 0; | ||
559 | torture_shutdown_absorb("torture_stutter"); | ||
560 | } while (!torture_must_stop()); | ||
561 | torture_kthread_stopping("torture_stutter"); | ||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | /* | ||
566 | * Initialize and kick off the torture_stutter kthread. | ||
567 | */ | ||
568 | int torture_stutter_init(int s) | ||
569 | { | ||
570 | int ret; | ||
571 | |||
572 | stutter = s; | ||
573 | ret = torture_create_kthread(torture_stutter, NULL, stutter_task); | ||
574 | return ret; | ||
575 | } | ||
576 | EXPORT_SYMBOL_GPL(torture_stutter_init); | ||
577 | |||
578 | /* | ||
579 | * Cleanup after the torture_stutter kthread. | ||
580 | */ | ||
581 | static void torture_stutter_cleanup(void) | ||
582 | { | ||
583 | if (!stutter_task) | ||
584 | return; | ||
585 | VERBOSE_TOROUT_STRING("Stopping torture_stutter task"); | ||
586 | kthread_stop(stutter_task); | ||
587 | stutter_task = NULL; | ||
588 | } | ||
589 | |||
590 | /* | ||
591 | * Initialize torture module. Please note that this is -not- invoked via | ||
592 | * the usual module_init() mechanism, but rather by an explicit call from | ||
593 | * the client torture module. This call must be paired with a later | ||
594 | * torture_init_end(). | ||
595 | * | ||
596 | * The runnable parameter points to a flag that controls whether or not | ||
597 | * the test is currently runnable. If there is no such flag, pass in NULL. | ||
598 | */ | ||
599 | void __init torture_init_begin(char *ttype, bool v, int *runnable) | ||
600 | { | ||
601 | mutex_lock(&fullstop_mutex); | ||
602 | torture_type = ttype; | ||
603 | verbose = v; | ||
604 | torture_runnable = runnable; | ||
605 | fullstop = FULLSTOP_DONTSTOP; | ||
606 | |||
607 | } | ||
608 | EXPORT_SYMBOL_GPL(torture_init_begin); | ||
609 | |||
610 | /* | ||
611 | * Tell the torture module that initialization is complete. | ||
612 | */ | ||
613 | void __init torture_init_end(void) | ||
614 | { | ||
615 | mutex_unlock(&fullstop_mutex); | ||
616 | register_reboot_notifier(&torture_shutdown_nb); | ||
617 | } | ||
618 | EXPORT_SYMBOL_GPL(torture_init_end); | ||
619 | |||
620 | /* | ||
621 | * Clean up torture module. Please note that this is -not- invoked via | ||
622 | * the usual module_exit() mechanism, but rather by an explicit call from | ||
623 | * the client torture module. Returns true if a race with system shutdown | ||
624 | * is detected, otherwise, all kthreads started by functions in this file | ||
625 | * will be shut down. | ||
626 | * | ||
627 | * This must be called before the caller starts shutting down its own | ||
628 | * kthreads. | ||
629 | */ | ||
630 | bool torture_cleanup(void) | ||
631 | { | ||
632 | mutex_lock(&fullstop_mutex); | ||
633 | if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) { | ||
634 | pr_warn("Concurrent rmmod and shutdown illegal!\n"); | ||
635 | mutex_unlock(&fullstop_mutex); | ||
636 | schedule_timeout_uninterruptible(10); | ||
637 | return true; | ||
638 | } | ||
639 | ACCESS_ONCE(fullstop) = FULLSTOP_RMMOD; | ||
640 | mutex_unlock(&fullstop_mutex); | ||
641 | torture_shutdown_cleanup(); | ||
642 | torture_shuffle_cleanup(); | ||
643 | torture_stutter_cleanup(); | ||
644 | torture_onoff_cleanup(); | ||
645 | return false; | ||
646 | } | ||
647 | EXPORT_SYMBOL_GPL(torture_cleanup); | ||
648 | |||
649 | /* | ||
650 | * Is it time for the current torture test to stop? | ||
651 | */ | ||
652 | bool torture_must_stop(void) | ||
653 | { | ||
654 | return torture_must_stop_irq() || kthread_should_stop(); | ||
655 | } | ||
656 | EXPORT_SYMBOL_GPL(torture_must_stop); | ||
657 | |||
658 | /* | ||
659 | * Is it time for the current torture test to stop? This is the irq-safe | ||
660 | * version, hence no check for kthread_should_stop(). | ||
661 | */ | ||
662 | bool torture_must_stop_irq(void) | ||
663 | { | ||
664 | return ACCESS_ONCE(fullstop) != FULLSTOP_DONTSTOP; | ||
665 | } | ||
666 | EXPORT_SYMBOL_GPL(torture_must_stop_irq); | ||
667 | |||
668 | /* | ||
669 | * Each kthread must wait for kthread_should_stop() before returning from | ||
670 | * its top-level function, otherwise segfaults ensue. This function | ||
671 | * prints a "stopping" message and waits for kthread_should_stop(), and | ||
672 | * should be called from all torture kthreads immediately prior to | ||
673 | * returning. | ||
674 | */ | ||
675 | void torture_kthread_stopping(char *title) | ||
676 | { | ||
677 | if (verbose) | ||
678 | VERBOSE_TOROUT_STRING(title); | ||
679 | while (!kthread_should_stop()) { | ||
680 | torture_shutdown_absorb(title); | ||
681 | schedule_timeout_uninterruptible(1); | ||
682 | } | ||
683 | } | ||
684 | EXPORT_SYMBOL_GPL(torture_kthread_stopping); | ||
685 | |||
686 | /* | ||
687 | * Create a generic torture kthread that is immediately runnable. If you | ||
688 | * need the kthread to be stopped so that you can do something to it before | ||
689 | * it starts, you will need to open-code your own. | ||
690 | */ | ||
691 | int _torture_create_kthread(int (*fn)(void *arg), void *arg, char *s, char *m, | ||
692 | char *f, struct task_struct **tp) | ||
693 | { | ||
694 | int ret = 0; | ||
695 | |||
696 | VERBOSE_TOROUT_STRING(m); | ||
697 | *tp = kthread_run(fn, arg, s); | ||
698 | if (IS_ERR(*tp)) { | ||
699 | ret = PTR_ERR(*tp); | ||
700 | VERBOSE_TOROUT_ERRSTRING(f); | ||
701 | *tp = NULL; | ||
702 | } | ||
703 | torture_shuffle_task_register(*tp); | ||
704 | return ret; | ||
705 | } | ||
706 | EXPORT_SYMBOL_GPL(_torture_create_kthread); | ||
707 | |||
708 | /* | ||
709 | * Stop a generic kthread, emitting a message. | ||
710 | */ | ||
711 | void _torture_stop_kthread(char *m, struct task_struct **tp) | ||
712 | { | ||
713 | if (*tp == NULL) | ||
714 | return; | ||
715 | VERBOSE_TOROUT_STRING(m); | ||
716 | kthread_stop(*tp); | ||
717 | *tp = NULL; | ||
718 | } | ||
719 | EXPORT_SYMBOL_GPL(_torture_stop_kthread); | ||
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index a48abeac753f..dd7f8858188a 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -980,6 +980,21 @@ config DEBUG_LOCKING_API_SELFTESTS | |||
980 | The following locking APIs are covered: spinlocks, rwlocks, | 980 | The following locking APIs are covered: spinlocks, rwlocks, |
981 | mutexes and rwsems. | 981 | mutexes and rwsems. |
982 | 982 | ||
983 | config LOCK_TORTURE_TEST | ||
984 | tristate "torture tests for locking" | ||
985 | depends on DEBUG_KERNEL | ||
986 | select TORTURE_TEST | ||
987 | default n | ||
988 | help | ||
989 | This option provides a kernel module that runs torture tests | ||
990 | on kernel locking primitives. The kernel module may be built | ||
991 | after the fact on the running kernel to be tested, if desired. | ||
992 | |||
993 | Say Y here if you want kernel locking-primitive torture tests | ||
994 | to be built into the kernel. | ||
995 | Say M if you want these torture tests to build as a module. | ||
996 | Say N if you are unsure. | ||
997 | |||
983 | endmenu # lock debugging | 998 | endmenu # lock debugging |
984 | 999 | ||
985 | config TRACE_IRQFLAGS | 1000 | config TRACE_IRQFLAGS |
@@ -1141,9 +1156,14 @@ config SPARSE_RCU_POINTER | |||
1141 | 1156 | ||
1142 | Say N if you are unsure. | 1157 | Say N if you are unsure. |
1143 | 1158 | ||
1159 | config TORTURE_TEST | ||
1160 | tristate | ||
1161 | default n | ||
1162 | |||
1144 | config RCU_TORTURE_TEST | 1163 | config RCU_TORTURE_TEST |
1145 | tristate "torture tests for RCU" | 1164 | tristate "torture tests for RCU" |
1146 | depends on DEBUG_KERNEL | 1165 | depends on DEBUG_KERNEL |
1166 | select TORTURE_TEST | ||
1147 | default n | 1167 | default n |
1148 | help | 1168 | help |
1149 | This option provides a kernel module that runs torture tests | 1169 | This option provides a kernel module that runs torture tests |
diff --git a/tools/testing/selftests/rcutorture/bin/functions.sh b/tools/testing/selftests/rcutorture/bin/functions.sh index 587561d7c035..9b17e810ddc3 100644 --- a/tools/testing/selftests/rcutorture/bin/functions.sh +++ b/tools/testing/selftests/rcutorture/bin/functions.sh | |||
@@ -96,6 +96,7 @@ identify_qemu () { | |||
96 | echo qemu-system-ppc64 | 96 | echo qemu-system-ppc64 |
97 | else | 97 | else |
98 | echo Cannot figure out what qemu command to use! 1>&2 | 98 | echo Cannot figure out what qemu command to use! 1>&2 |
99 | echo file $1 output: $u | ||
99 | # Usually this will be one of /usr/bin/qemu-system-* | 100 | # Usually this will be one of /usr/bin/qemu-system-* |
100 | # Use RCU_QEMU_CMD environment variable or appropriate | 101 | # Use RCU_QEMU_CMD environment variable or appropriate |
101 | # argument to top-level script. | 102 | # argument to top-level script. |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-lock.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-lock.sh new file mode 100755 index 000000000000..829186e19eb1 --- /dev/null +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-lock.sh | |||
@@ -0,0 +1,51 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # Analyze a given results directory for locktorture progress. | ||
4 | # | ||
5 | # Usage: sh kvm-recheck-lock.sh resdir | ||
6 | # | ||
7 | # This program is free software; you can redistribute it and/or modify | ||
8 | # it under the terms of the GNU General Public License as published by | ||
9 | # the Free Software Foundation; either version 2 of the License, or | ||
10 | # (at your option) any later version. | ||
11 | # | ||
12 | # This program is distributed in the hope that it will be useful, | ||
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | # GNU General Public License for more details. | ||
16 | # | ||
17 | # You should have received a copy of the GNU General Public License | ||
18 | # along with this program; if not, you can access it online at | ||
19 | # http://www.gnu.org/licenses/gpl-2.0.html. | ||
20 | # | ||
21 | # Copyright (C) IBM Corporation, 2014 | ||
22 | # | ||
23 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | ||
24 | |||
25 | i="$1" | ||
26 | if test -d $i | ||
27 | then | ||
28 | : | ||
29 | else | ||
30 | echo Unreadable results directory: $i | ||
31 | exit 1 | ||
32 | fi | ||
33 | |||
34 | configfile=`echo $i | sed -e 's/^.*\///'` | ||
35 | ncs=`grep "Writes: Total:" $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* Total: //' -e 's/ .*$//'` | ||
36 | if test -z "$ncs" | ||
37 | then | ||
38 | echo $configfile | ||
39 | else | ||
40 | title="$configfile ------- $ncs acquisitions/releases" | ||
41 | dur=`sed -e 's/^.* locktorture.shutdown_secs=//' -e 's/ .*$//' < $i/qemu-cmd 2> /dev/null` | ||
42 | if test -z "$dur" | ||
43 | then | ||
44 | : | ||
45 | else | ||
46 | ncsps=`awk -v ncs=$ncs -v dur=$dur ' | ||
47 | BEGIN { print ncs / dur }' < /dev/null` | ||
48 | title="$title ($ncsps per second)" | ||
49 | fi | ||
50 | echo $title | ||
51 | fi | ||
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh new file mode 100755 index 000000000000..d75b1dc5ae53 --- /dev/null +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh | |||
@@ -0,0 +1,51 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # Analyze a given results directory for rcutorture progress. | ||
4 | # | ||
5 | # Usage: sh kvm-recheck-rcu.sh resdir | ||
6 | # | ||
7 | # This program is free software; you can redistribute it and/or modify | ||
8 | # it under the terms of the GNU General Public License as published by | ||
9 | # the Free Software Foundation; either version 2 of the License, or | ||
10 | # (at your option) any later version. | ||
11 | # | ||
12 | # This program is distributed in the hope that it will be useful, | ||
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | # GNU General Public License for more details. | ||
16 | # | ||
17 | # You should have received a copy of the GNU General Public License | ||
18 | # along with this program; if not, you can access it online at | ||
19 | # http://www.gnu.org/licenses/gpl-2.0.html. | ||
20 | # | ||
21 | # Copyright (C) IBM Corporation, 2014 | ||
22 | # | ||
23 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | ||
24 | |||
25 | i="$1" | ||
26 | if test -d $i | ||
27 | then | ||
28 | : | ||
29 | else | ||
30 | echo Unreadable results directory: $i | ||
31 | exit 1 | ||
32 | fi | ||
33 | |||
34 | configfile=`echo $i | sed -e 's/^.*\///'` | ||
35 | ngps=`grep ver: $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* ver: //' -e 's/ .*$//'` | ||
36 | if test -z "$ngps" | ||
37 | then | ||
38 | echo $configfile | ||
39 | else | ||
40 | title="$configfile ------- $ngps grace periods" | ||
41 | dur=`sed -e 's/^.* rcutorture.shutdown_secs=//' -e 's/ .*$//' < $i/qemu-cmd 2> /dev/null` | ||
42 | if test -z "$dur" | ||
43 | then | ||
44 | : | ||
45 | else | ||
46 | ngpsps=`awk -v ngps=$ngps -v dur=$dur ' | ||
47 | BEGIN { print ngps / dur }' < /dev/null` | ||
48 | title="$title ($ngpsps per second)" | ||
49 | fi | ||
50 | echo $title | ||
51 | fi | ||
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh index baef09f3469b..a44daaa259a9 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | # | 2 | # |
3 | # Given the results directories for previous KVM runs of rcutorture, | 3 | # Given the results directories for previous KVM-based torture runs, |
4 | # check the build and console output for errors. Given a directory | 4 | # check the build and console output for errors. Given a directory |
5 | # containing results directories, this recursively checks them all. | 5 | # containing results directories, this recursively checks them all. |
6 | # | 6 | # |
@@ -27,11 +27,18 @@ | |||
27 | PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH | 27 | PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH |
28 | for rd in "$@" | 28 | for rd in "$@" |
29 | do | 29 | do |
30 | firsttime=1 | ||
30 | dirs=`find $rd -name Make.defconfig.out -print | sort | sed -e 's,/[^/]*$,,' | sort -u` | 31 | dirs=`find $rd -name Make.defconfig.out -print | sort | sed -e 's,/[^/]*$,,' | sort -u` |
31 | for i in $dirs | 32 | for i in $dirs |
32 | do | 33 | do |
33 | configfile=`echo $i | sed -e 's/^.*\///'` | 34 | if test -n "$firsttime" |
34 | echo $configfile | 35 | then |
36 | firsttime="" | ||
37 | resdir=`echo $i | sed -e 's,/$,,' -e 's,/[^/]*$,,'` | ||
38 | head -1 $resdir/log | ||
39 | fi | ||
40 | TORTURE_SUITE="`cat $i/../TORTURE_SUITE`" | ||
41 | kvm-recheck-${TORTURE_SUITE}.sh $i | ||
35 | configcheck.sh $i/.config $i/ConfigFragment | 42 | configcheck.sh $i/.config $i/ConfigFragment |
36 | parse-build.sh $i/Make.out $configfile | 43 | parse-build.sh $i/Make.out $configfile |
37 | parse-rcutorture.sh $i/console.log $configfile | 44 | parse-rcutorture.sh $i/console.log $configfile |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-rcu.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh index 151b23788935..94b28bb37d36 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-rcu.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh | |||
@@ -6,15 +6,15 @@ | |||
6 | # Execute this in the source tree. Do not run it as a background task | 6 | # Execute this in the source tree. Do not run it as a background task |
7 | # because qemu does not seem to like that much. | 7 | # because qemu does not seem to like that much. |
8 | # | 8 | # |
9 | # Usage: sh kvm-test-1-rcu.sh config builddir resdir minutes qemu-args bootargs | 9 | # Usage: sh kvm-test-1-run.sh config builddir resdir minutes qemu-args boot_args |
10 | # | 10 | # |
11 | # qemu-args defaults to "" -- you will want "-nographic" if running headless. | 11 | # qemu-args defaults to "-nographic", along with arguments specifying the |
12 | # bootargs defaults to "root=/dev/sda noapic selinux=0 console=ttyS0" | 12 | # number of CPUs and other options generated from |
13 | # "initcall_debug debug rcutorture.stat_interval=15" | 13 | # the underlying CPU architecture. |
14 | # "rcutorture.shutdown_secs=$((minutes * 60))" | 14 | # boot_args defaults to value returned by the per_version_boot_params |
15 | # "rcutorture.rcutorture_runnable=1" | 15 | # shell function. |
16 | # | 16 | # |
17 | # Anything you specify for either qemu-args or bootargs is appended to | 17 | # Anything you specify for either qemu-args or boot_args is appended to |
18 | # the default values. The "-smp" value is deduced from the contents of | 18 | # the default values. The "-smp" value is deduced from the contents of |
19 | # the config fragment. | 19 | # the config fragment. |
20 | # | 20 | # |
@@ -40,32 +40,34 @@ | |||
40 | 40 | ||
41 | grace=120 | 41 | grace=120 |
42 | 42 | ||
43 | T=/tmp/kvm-test-1-rcu.sh.$$ | 43 | T=/tmp/kvm-test-1-run.sh.$$ |
44 | trap 'rm -rf $T' 0 | 44 | trap 'rm -rf $T' 0 |
45 | 45 | ||
46 | . $KVM/bin/functions.sh | 46 | . $KVM/bin/functions.sh |
47 | . $KVPATH/ver_functions.sh | 47 | . $KVPATH/ver_functions.sh |
48 | 48 | ||
49 | config_template=${1} | 49 | config_template=${1} |
50 | config_dir=`echo $config_template | sed -e 's,/[^/]*$,,'` | ||
50 | title=`echo $config_template | sed -e 's/^.*\///'` | 51 | title=`echo $config_template | sed -e 's/^.*\///'` |
51 | builddir=${2} | 52 | builddir=${2} |
52 | if test -z "$builddir" -o ! -d "$builddir" -o ! -w "$builddir" | 53 | if test -z "$builddir" -o ! -d "$builddir" -o ! -w "$builddir" |
53 | then | 54 | then |
54 | echo "kvm-test-1-rcu.sh :$builddir: Not a writable directory, cannot build into it" | 55 | echo "kvm-test-1-run.sh :$builddir: Not a writable directory, cannot build into it" |
55 | exit 1 | 56 | exit 1 |
56 | fi | 57 | fi |
57 | resdir=${3} | 58 | resdir=${3} |
58 | if test -z "$resdir" -o ! -d "$resdir" -o ! -w "$resdir" | 59 | if test -z "$resdir" -o ! -d "$resdir" -o ! -w "$resdir" |
59 | then | 60 | then |
60 | echo "kvm-test-1-rcu.sh :$resdir: Not a writable directory, cannot build into it" | 61 | echo "kvm-test-1-run.sh :$resdir: Not a writable directory, cannot store results into it" |
61 | exit 1 | 62 | exit 1 |
62 | fi | 63 | fi |
63 | cp $config_template $resdir/ConfigFragment | 64 | cp $config_template $resdir/ConfigFragment |
64 | echo ' ---' `date`: Starting build | 65 | echo ' ---' `date`: Starting build |
65 | echo ' ---' Kconfig fragment at: $config_template >> $resdir/log | 66 | echo ' ---' Kconfig fragment at: $config_template >> $resdir/log |
66 | cat << '___EOF___' >> $T | 67 | if test -r "$config_dir/CFcommon" |
67 | CONFIG_RCU_TORTURE_TEST=y | 68 | then |
68 | ___EOF___ | 69 | cat < $config_dir/CFcommon >> $T |
70 | fi | ||
69 | # Optimizations below this point | 71 | # Optimizations below this point |
70 | # CONFIG_USB=n | 72 | # CONFIG_USB=n |
71 | # CONFIG_SECURITY=n | 73 | # CONFIG_SECURITY=n |
@@ -96,11 +98,23 @@ then | |||
96 | cp $builddir/.config $resdir | 98 | cp $builddir/.config $resdir |
97 | cp $builddir/arch/x86/boot/bzImage $resdir | 99 | cp $builddir/arch/x86/boot/bzImage $resdir |
98 | parse-build.sh $resdir/Make.out $title | 100 | parse-build.sh $resdir/Make.out $title |
101 | if test -f $builddir.wait | ||
102 | then | ||
103 | mv $builddir.wait $builddir.ready | ||
104 | fi | ||
99 | else | 105 | else |
100 | cp $builddir/Make*.out $resdir | 106 | cp $builddir/Make*.out $resdir |
101 | echo Build failed, not running KVM, see $resdir. | 107 | echo Build failed, not running KVM, see $resdir. |
108 | if test -f $builddir.wait | ||
109 | then | ||
110 | mv $builddir.wait $builddir.ready | ||
111 | fi | ||
102 | exit 1 | 112 | exit 1 |
103 | fi | 113 | fi |
114 | while test -f $builddir.ready | ||
115 | do | ||
116 | sleep 1 | ||
117 | done | ||
104 | minutes=$4 | 118 | minutes=$4 |
105 | seconds=$(($minutes * 60)) | 119 | seconds=$(($minutes * 60)) |
106 | qemu_args=$5 | 120 | qemu_args=$5 |
@@ -111,9 +125,10 @@ kstarttime=`awk 'BEGIN { print systime() }' < /dev/null` | |||
111 | echo ' ---' `date`: Starting kernel | 125 | echo ' ---' `date`: Starting kernel |
112 | 126 | ||
113 | # Determine the appropriate flavor of qemu command. | 127 | # Determine the appropriate flavor of qemu command. |
114 | QEMU="`identify_qemu $builddir/vmlinux.o`" | 128 | QEMU="`identify_qemu $builddir/vmlinux`" |
115 | 129 | ||
116 | # Generate -smp qemu argument. | 130 | # Generate -smp qemu argument. |
131 | qemu_args="-nographic $qemu_args" | ||
117 | cpu_count=`configNR_CPUS.sh $config_template` | 132 | cpu_count=`configNR_CPUS.sh $config_template` |
118 | vcpus=`identify_qemu_vcpus` | 133 | vcpus=`identify_qemu_vcpus` |
119 | if test $cpu_count -gt $vcpus | 134 | if test $cpu_count -gt $vcpus |
@@ -133,12 +148,8 @@ qemu_append="`identify_qemu_append "$QEMU"`" | |||
133 | 148 | ||
134 | # Pull in Kconfig-fragment boot parameters | 149 | # Pull in Kconfig-fragment boot parameters |
135 | boot_args="`configfrag_boot_params "$boot_args" "$config_template"`" | 150 | boot_args="`configfrag_boot_params "$boot_args" "$config_template"`" |
136 | # Generate CPU-hotplug boot parameters | 151 | # Generate kernel-version-specific boot parameters |
137 | boot_args="`rcutorture_param_onoff "$boot_args" $builddir/.config`" | 152 | boot_args="`per_version_boot_params "$boot_args" $builddir/.config $seconds`" |
138 | # Generate rcu_barrier() boot parameter | ||
139 | boot_args="`rcutorture_param_n_barrier_cbs "$boot_args"`" | ||
140 | # Pull in standard rcutorture boot arguments | ||
141 | boot_args="$boot_args rcutorture.stat_interval=15 rcutorture.shutdown_secs=$seconds rcutorture.rcutorture_runnable=1" | ||
142 | 153 | ||
143 | echo $QEMU $qemu_args -m 512 -kernel $builddir/arch/x86/boot/bzImage -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd | 154 | echo $QEMU $qemu_args -m 512 -kernel $builddir/arch/x86/boot/bzImage -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd |
144 | if test -n "$RCU_BUILDONLY" | 155 | if test -n "$RCU_BUILDONLY" |
@@ -188,5 +199,5 @@ then | |||
188 | fi | 199 | fi |
189 | 200 | ||
190 | cp $builddir/console.log $resdir | 201 | cp $builddir/console.log $resdir |
191 | parse-rcutorture.sh $resdir/console.log $title | 202 | parse-${TORTURE_SUITE}torture.sh $resdir/console.log $title |
192 | parse-console.sh $resdir/console.log $title | 203 | parse-console.sh $resdir/console.log $title |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh index 1b7923bf6a70..5a78cbf55f06 100644 --- a/tools/testing/selftests/rcutorture/bin/kvm.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm.sh | |||
@@ -30,14 +30,21 @@ | |||
30 | scriptname=$0 | 30 | scriptname=$0 |
31 | args="$*" | 31 | args="$*" |
32 | 32 | ||
33 | T=/tmp/kvm.sh.$$ | ||
34 | trap 'rm -rf $T' 0 | ||
35 | mkdir $T | ||
36 | |||
33 | dur=30 | 37 | dur=30 |
38 | dryrun="" | ||
34 | KVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM | 39 | KVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM |
35 | PATH=${KVM}/bin:$PATH; export PATH | 40 | PATH=${KVM}/bin:$PATH; export PATH |
36 | builddir="${KVM}/b1" | 41 | builddir="${KVM}/b1" |
37 | RCU_INITRD="$KVM/initrd"; export RCU_INITRD | 42 | RCU_INITRD="$KVM/initrd"; export RCU_INITRD |
38 | RCU_KMAKE_ARG=""; export RCU_KMAKE_ARG | 43 | RCU_KMAKE_ARG=""; export RCU_KMAKE_ARG |
44 | TORTURE_SUITE=rcu | ||
39 | resdir="" | 45 | resdir="" |
40 | configs="" | 46 | configs="" |
47 | cpus=0 | ||
41 | ds=`date +%Y.%m.%d-%H:%M:%S` | 48 | ds=`date +%Y.%m.%d-%H:%M:%S` |
42 | kversion="" | 49 | kversion="" |
43 | 50 | ||
@@ -49,7 +56,9 @@ usage () { | |||
49 | echo " --builddir absolute-pathname" | 56 | echo " --builddir absolute-pathname" |
50 | echo " --buildonly" | 57 | echo " --buildonly" |
51 | echo " --configs \"config-file list\"" | 58 | echo " --configs \"config-file list\"" |
59 | echo " --cpus N" | ||
52 | echo " --datestamp string" | 60 | echo " --datestamp string" |
61 | echo " --dryrun sched|script" | ||
53 | echo " --duration minutes" | 62 | echo " --duration minutes" |
54 | echo " --interactive" | 63 | echo " --interactive" |
55 | echo " --kmake-arg kernel-make-arguments" | 64 | echo " --kmake-arg kernel-make-arguments" |
@@ -58,8 +67,9 @@ usage () { | |||
58 | echo " --no-initrd" | 67 | echo " --no-initrd" |
59 | echo " --qemu-args qemu-system-..." | 68 | echo " --qemu-args qemu-system-..." |
60 | echo " --qemu-cmd qemu-system-..." | 69 | echo " --qemu-cmd qemu-system-..." |
61 | echo " --results absolute-pathname" | ||
62 | echo " --relbuilddir relative-pathname" | 70 | echo " --relbuilddir relative-pathname" |
71 | echo " --results absolute-pathname" | ||
72 | echo " --torture rcu" | ||
63 | exit 1 | 73 | exit 1 |
64 | } | 74 | } |
65 | 75 | ||
@@ -85,11 +95,21 @@ do | |||
85 | configs="$2" | 95 | configs="$2" |
86 | shift | 96 | shift |
87 | ;; | 97 | ;; |
98 | --cpus) | ||
99 | checkarg --cpus "(number)" "$#" "$2" '^[0-9]*$' '^--' | ||
100 | cpus=$2 | ||
101 | shift | ||
102 | ;; | ||
88 | --datestamp) | 103 | --datestamp) |
89 | checkarg --datestamp "(relative pathname)" "$#" "$2" '^[^/]*$' '^--' | 104 | checkarg --datestamp "(relative pathname)" "$#" "$2" '^[^/]*$' '^--' |
90 | ds=$2 | 105 | ds=$2 |
91 | shift | 106 | shift |
92 | ;; | 107 | ;; |
108 | --dryrun) | ||
109 | checkarg --dryrun "sched|script" $# "$2" 'sched\|script' '^--' | ||
110 | dryrun=$2 | ||
111 | shift | ||
112 | ;; | ||
93 | --duration) | 113 | --duration) |
94 | checkarg --duration "(minutes)" $# "$2" '^[0-9]*$' '^error' | 114 | checkarg --duration "(minutes)" $# "$2" '^[0-9]*$' '^error' |
95 | dur=$2 | 115 | dur=$2 |
@@ -138,6 +158,11 @@ do | |||
138 | resdir=$2 | 158 | resdir=$2 |
139 | shift | 159 | shift |
140 | ;; | 160 | ;; |
161 | --torture) | ||
162 | checkarg --torture "(suite name)" "$#" "$2" '^\(lock\|rcu\)$' '^--' | ||
163 | TORTURE_SUITE=$2 | ||
164 | shift | ||
165 | ;; | ||
141 | *) | 166 | *) |
142 | echo Unknown argument $1 | 167 | echo Unknown argument $1 |
143 | usage | 168 | usage |
@@ -146,7 +171,7 @@ do | |||
146 | shift | 171 | shift |
147 | done | 172 | done |
148 | 173 | ||
149 | CONFIGFRAG=${KVM}/configs; export CONFIGFRAG | 174 | CONFIGFRAG=${KVM}/configs/${TORTURE_SUITE}; export CONFIGFRAG |
150 | KVPATH=${CONFIGFRAG}/$kversion; export KVPATH | 175 | KVPATH=${CONFIGFRAG}/$kversion; export KVPATH |
151 | 176 | ||
152 | if test -z "$configs" | 177 | if test -z "$configs" |
@@ -157,54 +182,231 @@ fi | |||
157 | if test -z "$resdir" | 182 | if test -z "$resdir" |
158 | then | 183 | then |
159 | resdir=$KVM/res | 184 | resdir=$KVM/res |
160 | if ! test -e $resdir | 185 | fi |
161 | then | 186 | |
162 | mkdir $resdir || : | 187 | if test "$dryrun" = "" |
163 | fi | 188 | then |
164 | else | ||
165 | if ! test -e $resdir | 189 | if ! test -e $resdir |
166 | then | 190 | then |
167 | mkdir -p "$resdir" || : | 191 | mkdir -p "$resdir" || : |
168 | fi | 192 | fi |
169 | fi | 193 | mkdir $resdir/$ds |
170 | mkdir $resdir/$ds | ||
171 | touch $resdir/$ds/log | ||
172 | echo $scriptname $args >> $resdir/$ds/log | ||
173 | 194 | ||
174 | pwd > $resdir/$ds/testid.txt | 195 | # Be noisy only if running the script. |
175 | if test -d .git | 196 | echo Results directory: $resdir/$ds |
176 | then | 197 | echo $scriptname $args |
177 | git status >> $resdir/$ds/testid.txt | 198 | |
178 | git rev-parse HEAD >> $resdir/$ds/testid.txt | 199 | touch $resdir/$ds/log |
179 | fi | 200 | echo $scriptname $args >> $resdir/$ds/log |
180 | builddir=$KVM/b1 | 201 | echo ${TORTURE_SUITE} > $resdir/$ds/TORTURE_SUITE |
181 | if ! test -e $builddir | 202 | |
182 | then | 203 | pwd > $resdir/$ds/testid.txt |
183 | mkdir $builddir || : | 204 | if test -d .git |
205 | then | ||
206 | git status >> $resdir/$ds/testid.txt | ||
207 | git rev-parse HEAD >> $resdir/$ds/testid.txt | ||
208 | fi | ||
184 | fi | 209 | fi |
185 | 210 | ||
211 | # Create a file of test-name/#cpus pairs, sorted by decreasing #cpus. | ||
212 | touch $T/cfgcpu | ||
186 | for CF in $configs | 213 | for CF in $configs |
187 | do | 214 | do |
188 | # Running TREE01 multiple times creates TREE01, TREE01.2, TREE01.3, ... | 215 | if test -f "$CONFIGFRAG/$kversion/$CF" |
189 | rd=$resdir/$ds/$CF | ||
190 | if test -d "${rd}" | ||
191 | then | 216 | then |
192 | n="`ls -d "${rd}"* | grep '\.[0-9]\+$' | | 217 | echo $CF `configNR_CPUS.sh $CONFIGFRAG/$kversion/$CF` >> $T/cfgcpu |
193 | sed -e 's/^.*\.\([0-9]\+\)/\1/' | | 218 | else |
194 | sort -k1n | tail -1`" | 219 | echo "The --configs file $CF does not exist, terminating." |
195 | if test -z "$n" | 220 | exit 1 |
196 | then | ||
197 | rd="${rd}.2" | ||
198 | else | ||
199 | n="`expr $n + 1`" | ||
200 | rd="${rd}.${n}" | ||
201 | fi | ||
202 | fi | 221 | fi |
203 | mkdir "${rd}" | ||
204 | echo Results directory: $rd | ||
205 | kvm-test-1-rcu.sh $CONFIGFRAG/$kversion/$CF $builddir $rd $dur "-nographic $RCU_QEMU_ARG" "rcutorture.test_no_idle_hz=1 rcutorture.verbose=1 $RCU_BOOTARGS" | ||
206 | done | 222 | done |
223 | sort -k2nr $T/cfgcpu > $T/cfgcpu.sort | ||
224 | |||
225 | # Use a greedy bin-packing algorithm, sorting the list accordingly. | ||
226 | awk < $T/cfgcpu.sort > $T/cfgcpu.pack -v ncpus=$cpus ' | ||
227 | BEGIN { | ||
228 | njobs = 0; | ||
229 | } | ||
230 | |||
231 | { | ||
232 | # Read file of tests and corresponding required numbers of CPUs. | ||
233 | cf[njobs] = $1; | ||
234 | cpus[njobs] = $2; | ||
235 | njobs++; | ||
236 | } | ||
237 | |||
238 | END { | ||
239 | alldone = 0; | ||
240 | batch = 0; | ||
241 | nc = -1; | ||
242 | |||
243 | # Each pass through the following loop creates on test batch | ||
244 | # that can be executed concurrently given ncpus. Note that a | ||
245 | # given test that requires more than the available CPUs will run in | ||
246 | # their own batch. Such tests just have to make do with what | ||
247 | # is available. | ||
248 | while (nc != ncpus) { | ||
249 | batch++; | ||
250 | nc = ncpus; | ||
251 | |||
252 | # Each pass through the following loop considers one | ||
253 | # test for inclusion in the current batch. | ||
254 | for (i = 0; i < njobs; i++) { | ||
255 | if (done[i]) | ||
256 | continue; # Already part of a batch. | ||
257 | if (nc >= cpus[i] || nc == ncpus) { | ||
258 | |||
259 | # This test fits into the current batch. | ||
260 | done[i] = batch; | ||
261 | nc -= cpus[i]; | ||
262 | if (nc <= 0) | ||
263 | break; # Too-big test in its own batch. | ||
264 | } | ||
265 | } | ||
266 | } | ||
267 | |||
268 | # Dump out the tests in batch order. | ||
269 | for (b = 1; b <= batch; b++) | ||
270 | for (i = 0; i < njobs; i++) | ||
271 | if (done[i] == b) | ||
272 | print cf[i], cpus[i]; | ||
273 | }' | ||
274 | |||
275 | # Generate a script to execute the tests in appropriate batches. | ||
276 | cat << ___EOF___ > $T/script | ||
277 | TORTURE_SUITE="$TORTURE_SUITE"; export TORTURE_SUITE | ||
278 | ___EOF___ | ||
279 | awk < $T/cfgcpu.pack \ | ||
280 | -v CONFIGDIR="$CONFIGFRAG/$kversion/" \ | ||
281 | -v KVM="$KVM" \ | ||
282 | -v ncpus=$cpus \ | ||
283 | -v rd=$resdir/$ds/ \ | ||
284 | -v dur=$dur \ | ||
285 | -v RCU_QEMU_ARG=$RCU_QEMU_ARG \ | ||
286 | -v RCU_BOOTARGS=$RCU_BOOTARGS \ | ||
287 | 'BEGIN { | ||
288 | i = 0; | ||
289 | } | ||
290 | |||
291 | { | ||
292 | cf[i] = $1; | ||
293 | cpus[i] = $2; | ||
294 | i++; | ||
295 | } | ||
296 | |||
297 | # Dump out the scripting required to run one test batch. | ||
298 | function dump(first, pastlast) | ||
299 | { | ||
300 | print "echo ----Start batch: `date`"; | ||
301 | print "echo ----Start batch: `date` >> " rd "/log"; | ||
302 | jn=1 | ||
303 | for (j = first; j < pastlast; j++) { | ||
304 | builddir=KVM "/b" jn | ||
305 | cpusr[jn] = cpus[j]; | ||
306 | if (cfrep[cf[j]] == "") { | ||
307 | cfr[jn] = cf[j]; | ||
308 | cfrep[cf[j]] = 1; | ||
309 | } else { | ||
310 | cfrep[cf[j]]++; | ||
311 | cfr[jn] = cf[j] "." cfrep[cf[j]]; | ||
312 | } | ||
313 | if (cpusr[jn] > ncpus && ncpus != 0) | ||
314 | ovf = "(!)"; | ||
315 | else | ||
316 | ovf = ""; | ||
317 | print "echo ", cfr[jn], cpusr[jn] ovf ": Starting build. `date`"; | ||
318 | print "echo ", cfr[jn], cpusr[jn] ovf ": Starting build. `date` >> " rd "/log"; | ||
319 | print "rm -f " builddir ".*"; | ||
320 | print "touch " builddir ".wait"; | ||
321 | print "mkdir " builddir " > /dev/null 2>&1 || :"; | ||
322 | print "mkdir " rd cfr[jn] " || :"; | ||
323 | print "kvm-test-1-run.sh " CONFIGDIR cf[j], builddir, rd cfr[jn], dur " \"" RCU_QEMU_ARG "\" \"" RCU_BOOTARGS "\" > " rd cfr[jn] "/kvm-test-1-run.sh.out 2>&1 &" | ||
324 | print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date`"; | ||
325 | print "echo ", cfr[jn], cpusr[jn] ovf ": Waiting for build to complete. `date` >> " rd "/log"; | ||
326 | print "while test -f " builddir ".wait" | ||
327 | print "do" | ||
328 | print "\tsleep 1" | ||
329 | print "done" | ||
330 | print "echo ", cfr[jn], cpusr[jn] ovf ": Build complete. `date`"; | ||
331 | print "echo ", cfr[jn], cpusr[jn] ovf ": Build complete. `date` >> " rd "/log"; | ||
332 | jn++; | ||
333 | } | ||
334 | for (j = 1; j < jn; j++) { | ||
335 | builddir=KVM "/b" j | ||
336 | print "rm -f " builddir ".ready" | ||
337 | print "echo ----", cfr[j], cpusr[j] ovf ": Starting kernel. `date`"; | ||
338 | print "echo ----", cfr[j], cpusr[j] ovf ": Starting kernel. `date` >> " rd "/log"; | ||
339 | } | ||
340 | print "wait" | ||
341 | print "echo ---- All kernel runs complete. `date`"; | ||
342 | print "echo ---- All kernel runs complete. `date` >> " rd "/log"; | ||
343 | for (j = 1; j < jn; j++) { | ||
344 | builddir=KVM "/b" j | ||
345 | print "echo ----", cfr[j], cpusr[j] ovf ": Build/run results:"; | ||
346 | print "echo ----", cfr[j], cpusr[j] ovf ": Build/run results: >> " rd "/log"; | ||
347 | print "cat " rd cfr[j] "/kvm-test-1-run.sh.out"; | ||
348 | print "cat " rd cfr[j] "/kvm-test-1-run.sh.out >> " rd "/log"; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | END { | ||
353 | njobs = i; | ||
354 | nc = ncpus; | ||
355 | first = 0; | ||
356 | |||
357 | # Each pass through the following loop considers one test. | ||
358 | for (i = 0; i < njobs; i++) { | ||
359 | if (ncpus == 0) { | ||
360 | # Sequential test specified, each test its own batch. | ||
361 | dump(i, i + 1); | ||
362 | first = i; | ||
363 | } else if (nc < cpus[i] && i != 0) { | ||
364 | # Out of CPUs, dump out a batch. | ||
365 | dump(first, i); | ||
366 | first = i; | ||
367 | nc = ncpus; | ||
368 | } | ||
369 | # Account for the CPUs needed by the current test. | ||
370 | nc -= cpus[i]; | ||
371 | } | ||
372 | # Dump the last batch. | ||
373 | if (ncpus != 0) | ||
374 | dump(first, i); | ||
375 | }' >> $T/script | ||
376 | |||
377 | if test "$dryrun" = script | ||
378 | then | ||
379 | # Dump out the script, but define the environment variables that | ||
380 | # it needs to run standalone. | ||
381 | echo CONFIGFRAG="$CONFIGFRAG; export CONFIGFRAG" | ||
382 | echo KVM="$KVM; export KVM" | ||
383 | echo KVPATH="$KVPATH; export KVPATH" | ||
384 | echo PATH="$PATH; export PATH" | ||
385 | echo RCU_BUILDONLY="$RCU_BUILDONLY; export RCU_BUILDONLY" | ||
386 | echo RCU_INITRD="$RCU_INITRD; export RCU_INITRD" | ||
387 | echo RCU_KMAKE_ARG="$RCU_KMAKE_ARG; export RCU_KMAKE_ARG" | ||
388 | echo RCU_QEMU_CMD="$RCU_QEMU_CMD; export RCU_QEMU_CMD" | ||
389 | echo RCU_QEMU_INTERACTIVE="$RCU_QEMU_INTERACTIVE; export RCU_QEMU_INTERACTIVE" | ||
390 | echo RCU_QEMU_MAC="$RCU_QEMU_MAC; export RCU_QEMU_MAC" | ||
391 | echo "mkdir -p "$resdir" || :" | ||
392 | echo "mkdir $resdir/$ds" | ||
393 | cat $T/script | ||
394 | exit 0 | ||
395 | elif test "$dryrun" = sched | ||
396 | then | ||
397 | # Extract the test run schedule from the script. | ||
398 | egrep 'start batch|Starting build\.' $T/script | | ||
399 | sed -e 's/:.*$//' -e 's/^echo //' | ||
400 | exit 0 | ||
401 | else | ||
402 | # Not a dryru, so run the script. | ||
403 | sh $T/script | ||
404 | fi | ||
405 | |||
207 | # 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 | 406 | # 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 |
208 | 407 | ||
408 | echo | ||
409 | echo | ||
209 | echo " --- `date` Test summary:" | 410 | echo " --- `date` Test summary:" |
411 | echo Results directory: $resdir/$ds | ||
210 | kvm-recheck.sh $resdir/$ds | 412 | kvm-recheck.sh $resdir/$ds |
diff --git a/tools/testing/selftests/rcutorture/configs/lock/BUSTED b/tools/testing/selftests/rcutorture/configs/lock/BUSTED new file mode 100644 index 000000000000..1d1da1477fc3 --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/lock/BUSTED | |||
@@ -0,0 +1,6 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_NR_CPUS=4 | ||
3 | CONFIG_HOTPLUG_CPU=y | ||
4 | CONFIG_PREEMPT_NONE=n | ||
5 | CONFIG_PREEMPT_VOLUNTARY=n | ||
6 | CONFIG_PREEMPT=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/lock/BUSTED.boot b/tools/testing/selftests/rcutorture/configs/lock/BUSTED.boot new file mode 100644 index 000000000000..6386c15e9770 --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/lock/BUSTED.boot | |||
@@ -0,0 +1 @@ | |||
locktorture.torture_type=lock_busted | |||
diff --git a/tools/testing/selftests/rcutorture/configs/lock/CFLIST b/tools/testing/selftests/rcutorture/configs/lock/CFLIST new file mode 100644 index 000000000000..a061b22d1892 --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/lock/CFLIST | |||
@@ -0,0 +1 @@ | |||
LOCK01 | |||
diff --git a/tools/testing/selftests/rcutorture/configs/lock/CFcommon b/tools/testing/selftests/rcutorture/configs/lock/CFcommon new file mode 100644 index 000000000000..e372dc269254 --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/lock/CFcommon | |||
@@ -0,0 +1,2 @@ | |||
1 | CONFIG_LOCK_TORTURE_TEST=y | ||
2 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK01 b/tools/testing/selftests/rcutorture/configs/lock/LOCK01 new file mode 100644 index 000000000000..a9625e3d6cd9 --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/lock/LOCK01 | |||
@@ -0,0 +1,6 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_NR_CPUS=8 | ||
3 | CONFIG_HOTPLUG_CPU=y | ||
4 | CONFIG_PREEMPT_NONE=n | ||
5 | CONFIG_PREEMPT_VOLUNTARY=n | ||
6 | CONFIG_PREEMPT=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/lock/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/lock/ver_functions.sh new file mode 100644 index 000000000000..9746ea1cd6c7 --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/lock/ver_functions.sh | |||
@@ -0,0 +1,43 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # Kernel-version-dependent shell functions for the rest of the scripts. | ||
4 | # | ||
5 | # This program is free software; you can redistribute it and/or modify | ||
6 | # it under the terms of the GNU General Public License as published by | ||
7 | # the Free Software Foundation; either version 2 of the License, or | ||
8 | # (at your option) any later version. | ||
9 | # | ||
10 | # This program is distributed in the hope that it will be useful, | ||
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | # GNU General Public License for more details. | ||
14 | # | ||
15 | # You should have received a copy of the GNU General Public License | ||
16 | # along with this program; if not, you can access it online at | ||
17 | # http://www.gnu.org/licenses/gpl-2.0.html. | ||
18 | # | ||
19 | # Copyright (C) IBM Corporation, 2014 | ||
20 | # | ||
21 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | ||
22 | |||
23 | # locktorture_param_onoff bootparam-string config-file | ||
24 | # | ||
25 | # Adds onoff locktorture module parameters to kernels having it. | ||
26 | locktorture_param_onoff () { | ||
27 | if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" | ||
28 | then | ||
29 | echo CPU-hotplug kernel, adding locktorture onoff. 1>&2 | ||
30 | echo locktorture.onoff_interval=3 locktorture.onoff_holdoff=30 | ||
31 | fi | ||
32 | } | ||
33 | |||
34 | # per_version_boot_params bootparam-string config-file seconds | ||
35 | # | ||
36 | # Adds per-version torture-module parameters to kernels supporting them. | ||
37 | per_version_boot_params () { | ||
38 | echo $1 `locktorture_param_onoff "$1" "$2"` \ | ||
39 | locktorture.stat_interval=15 \ | ||
40 | locktorture.shutdown_secs=$3 \ | ||
41 | locktorture.locktorture_runnable=1 \ | ||
42 | locktorture.verbose=1 | ||
43 | } | ||
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/BUSTED b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED new file mode 100644 index 000000000000..48d8a245c7fa --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED | |||
@@ -0,0 +1,7 @@ | |||
1 | CONFIG_RCU_TRACE=n | ||
2 | CONFIG_SMP=y | ||
3 | CONFIG_NR_CPUS=4 | ||
4 | CONFIG_HOTPLUG_CPU=y | ||
5 | CONFIG_PREEMPT_NONE=n | ||
6 | CONFIG_PREEMPT_VOLUNTARY=n | ||
7 | CONFIG_PREEMPT=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/BUSTED.boot b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED.boot new file mode 100644 index 000000000000..6804f9dcfc1b --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED.boot | |||
@@ -0,0 +1 @@ | |||
rcutorture.torture_type=rcu_busted | |||
diff --git a/tools/testing/selftests/rcutorture/configs/CFLIST b/tools/testing/selftests/rcutorture/configs/rcu/CFLIST index cd3d29cb0a47..cd3d29cb0a47 100644 --- a/tools/testing/selftests/rcutorture/configs/CFLIST +++ b/tools/testing/selftests/rcutorture/configs/rcu/CFLIST | |||
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/CFcommon b/tools/testing/selftests/rcutorture/configs/rcu/CFcommon new file mode 100644 index 000000000000..d2d2a86139db --- /dev/null +++ b/tools/testing/selftests/rcutorture/configs/rcu/CFcommon | |||
@@ -0,0 +1,2 @@ | |||
1 | CONFIG_RCU_TORTURE_TEST=y | ||
2 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/SRCU-N b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N index 10a0e27f4c75..9fbb41b9b314 100644 --- a/tools/testing/selftests/rcutorture/configs/SRCU-N +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N | |||
@@ -1,8 +1,7 @@ | |||
1 | CONFIG_RCU_TRACE=n | 1 | CONFIG_RCU_TRACE=n |
2 | CONFIG_SMP=y | 2 | CONFIG_SMP=y |
3 | CONFIG_NR_CPUS=8 | 3 | CONFIG_NR_CPUS=4 |
4 | CONFIG_HOTPLUG_CPU=y | 4 | CONFIG_HOTPLUG_CPU=y |
5 | CONFIG_PREEMPT_NONE=y | 5 | CONFIG_PREEMPT_NONE=y |
6 | CONFIG_PREEMPT_VOLUNTARY=n | 6 | CONFIG_PREEMPT_VOLUNTARY=n |
7 | CONFIG_PREEMPT=n | 7 | CONFIG_PREEMPT=n |
8 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/SRCU-N.boot b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot index 238bfe3bd0cc..238bfe3bd0cc 100644 --- a/tools/testing/selftests/rcutorture/configs/SRCU-N.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot | |||
diff --git a/tools/testing/selftests/rcutorture/configs/SRCU-P b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P index 6650e00c6d91..4b6f272dba27 100644 --- a/tools/testing/selftests/rcutorture/configs/SRCU-P +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P | |||
@@ -5,4 +5,3 @@ CONFIG_HOTPLUG_CPU=y | |||
5 | CONFIG_PREEMPT_NONE=n | 5 | CONFIG_PREEMPT_NONE=n |
6 | CONFIG_PREEMPT_VOLUNTARY=n | 6 | CONFIG_PREEMPT_VOLUNTARY=n |
7 | CONFIG_PREEMPT=y | 7 | CONFIG_PREEMPT=y |
8 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/SRCU-P.boot b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot index 238bfe3bd0cc..238bfe3bd0cc 100644 --- a/tools/testing/selftests/rcutorture/configs/SRCU-P.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot | |||
diff --git a/tools/testing/selftests/rcutorture/configs/TINY01 b/tools/testing/selftests/rcutorture/configs/rcu/TINY01 index 0c2823f21712..0a63e073a00c 100644 --- a/tools/testing/selftests/rcutorture/configs/TINY01 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TINY01 | |||
@@ -10,4 +10,3 @@ CONFIG_RCU_TRACE=n | |||
10 | CONFIG_DEBUG_LOCK_ALLOC=n | 10 | CONFIG_DEBUG_LOCK_ALLOC=n |
11 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 11 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
12 | CONFIG_PREEMPT_COUNT=n | 12 | CONFIG_PREEMPT_COUNT=n |
13 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TINY02 b/tools/testing/selftests/rcutorture/configs/rcu/TINY02 index e5072d7528b6..f4feaee40776 100644 --- a/tools/testing/selftests/rcutorture/configs/TINY02 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TINY02 | |||
@@ -10,4 +10,3 @@ CONFIG_RCU_TRACE=y | |||
10 | CONFIG_DEBUG_LOCK_ALLOC=y | 10 | CONFIG_DEBUG_LOCK_ALLOC=y |
11 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 11 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
12 | CONFIG_PREEMPT_COUNT=y | 12 | CONFIG_PREEMPT_COUNT=y |
13 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE01 b/tools/testing/selftests/rcutorture/configs/rcu/TREE01 index 141119a00044..9c827ec59a97 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE01 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE01 | |||
@@ -20,4 +20,3 @@ CONFIG_RCU_CPU_STALL_INFO=n | |||
20 | CONFIG_RCU_CPU_STALL_VERBOSE=n | 20 | CONFIG_RCU_CPU_STALL_VERBOSE=n |
21 | CONFIG_RCU_BOOST=n | 21 | CONFIG_RCU_BOOST=n |
22 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 22 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
23 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE01.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE01.boot index 0fc8a3428938..0fc8a3428938 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE01.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE01.boot | |||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE02 b/tools/testing/selftests/rcutorture/configs/rcu/TREE02 index 2d4d09608528..1a777b5f68b5 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE02 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE02 | |||
@@ -7,7 +7,7 @@ CONFIG_PREEMPT=y | |||
7 | CONFIG_HZ_PERIODIC=n | 7 | CONFIG_HZ_PERIODIC=n |
8 | CONFIG_NO_HZ_IDLE=y | 8 | CONFIG_NO_HZ_IDLE=y |
9 | CONFIG_NO_HZ_FULL=n | 9 | CONFIG_NO_HZ_FULL=n |
10 | CONFIG_RCU_FAST_NO_HZ=n | 10 | CONFIG_RCU_FAST_NO_HZ=n |
11 | CONFIG_RCU_TRACE=n | 11 | CONFIG_RCU_TRACE=n |
12 | CONFIG_HOTPLUG_CPU=n | 12 | CONFIG_HOTPLUG_CPU=n |
13 | CONFIG_SUSPEND=n | 13 | CONFIG_SUSPEND=n |
@@ -23,4 +23,3 @@ CONFIG_RCU_CPU_STALL_INFO=n | |||
23 | CONFIG_RCU_CPU_STALL_VERBOSE=y | 23 | CONFIG_RCU_CPU_STALL_VERBOSE=y |
24 | CONFIG_RCU_BOOST=n | 24 | CONFIG_RCU_BOOST=n |
25 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 25 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
26 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE03 b/tools/testing/selftests/rcutorture/configs/rcu/TREE03 index a47de5be8a04..c1f111c1561b 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE03 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE03 | |||
@@ -20,4 +20,3 @@ CONFIG_RCU_CPU_STALL_VERBOSE=n | |||
20 | CONFIG_RCU_BOOST=y | 20 | CONFIG_RCU_BOOST=y |
21 | CONFIG_RCU_BOOST_PRIO=2 | 21 | CONFIG_RCU_BOOST_PRIO=2 |
22 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 22 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
23 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE04 b/tools/testing/selftests/rcutorture/configs/rcu/TREE04 index 8d839b86a1d5..7dbd27ce17a4 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE04 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE04 | |||
@@ -22,4 +22,3 @@ CONFIG_PROVE_RCU_DELAY=n | |||
22 | CONFIG_RCU_CPU_STALL_INFO=y | 22 | CONFIG_RCU_CPU_STALL_INFO=y |
23 | CONFIG_RCU_CPU_STALL_VERBOSE=y | 23 | CONFIG_RCU_CPU_STALL_VERBOSE=y |
24 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 24 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
25 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE04.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE04.boot index 0fc8a3428938..0fc8a3428938 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE04.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE04.boot | |||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE05 b/tools/testing/selftests/rcutorture/configs/rcu/TREE05 index b5ba72ea25cb..d0f32e574743 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE05 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE05 | |||
@@ -22,4 +22,3 @@ CONFIG_PROVE_RCU_DELAY=y | |||
22 | CONFIG_RCU_CPU_STALL_INFO=n | 22 | CONFIG_RCU_CPU_STALL_INFO=n |
23 | CONFIG_RCU_CPU_STALL_VERBOSE=n | 23 | CONFIG_RCU_CPU_STALL_VERBOSE=n |
24 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 24 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
25 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE05.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE05.boot index 3b42b8b033cd..3b42b8b033cd 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE05.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE05.boot | |||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE06 b/tools/testing/selftests/rcutorture/configs/rcu/TREE06 index 7c95ab48d29f..2e477dfb9c57 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE06 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE06 | |||
@@ -23,4 +23,3 @@ CONFIG_PROVE_RCU_DELAY=n | |||
23 | CONFIG_RCU_CPU_STALL_INFO=n | 23 | CONFIG_RCU_CPU_STALL_INFO=n |
24 | CONFIG_RCU_CPU_STALL_VERBOSE=n | 24 | CONFIG_RCU_CPU_STALL_VERBOSE=n |
25 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=y | 25 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=y |
26 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE07 b/tools/testing/selftests/rcutorture/configs/rcu/TREE07 index 1467404bdec1..042f86ef362a 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE07 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE07 | |||
@@ -21,4 +21,3 @@ CONFIG_PROVE_RCU_DELAY=n | |||
21 | CONFIG_RCU_CPU_STALL_INFO=y | 21 | CONFIG_RCU_CPU_STALL_INFO=y |
22 | CONFIG_RCU_CPU_STALL_VERBOSE=n | 22 | CONFIG_RCU_CPU_STALL_VERBOSE=n |
23 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 23 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
24 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE08 b/tools/testing/selftests/rcutorture/configs/rcu/TREE08 index 7d097a61ac2a..3438cee1e3c5 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE08 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE08 | |||
@@ -23,4 +23,3 @@ CONFIG_RCU_CPU_STALL_INFO=n | |||
23 | CONFIG_RCU_CPU_STALL_VERBOSE=n | 23 | CONFIG_RCU_CPU_STALL_VERBOSE=n |
24 | CONFIG_RCU_BOOST=n | 24 | CONFIG_RCU_BOOST=n |
25 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 25 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
26 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE08-T b/tools/testing/selftests/rcutorture/configs/rcu/TREE08-T index 442c4e450ab3..bf4523d3e44c 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE08-T +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE08-T | |||
@@ -23,4 +23,3 @@ CONFIG_RCU_CPU_STALL_INFO=n | |||
23 | CONFIG_RCU_CPU_STALL_VERBOSE=n | 23 | CONFIG_RCU_CPU_STALL_VERBOSE=n |
24 | CONFIG_RCU_BOOST=n | 24 | CONFIG_RCU_BOOST=n |
25 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 25 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
26 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/TREE09 b/tools/testing/selftests/rcutorture/configs/rcu/TREE09 index 0d1ec0d3dfee..81e4f7c0bf0b 100644 --- a/tools/testing/selftests/rcutorture/configs/TREE09 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE09 | |||
@@ -18,4 +18,3 @@ CONFIG_RCU_CPU_STALL_INFO=n | |||
18 | CONFIG_RCU_CPU_STALL_VERBOSE=n | 18 | CONFIG_RCU_CPU_STALL_VERBOSE=n |
19 | CONFIG_RCU_BOOST=n | 19 | CONFIG_RCU_BOOST=n |
20 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 20 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
21 | CONFIG_PRINTK_TIME=y | ||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/CFLIST b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/CFLIST index 18223947bbcb..18223947bbcb 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/CFLIST +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/CFLIST | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/N1-S-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N1-S-T-NH-SD-SMP-HP index d3ef873eb6e7..d3ef873eb6e7 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/N1-S-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N1-S-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/N2-2-t-nh-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N2-2-t-nh-sd-SMP-hp index 02e418572b1b..02e418572b1b 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/N2-2-t-nh-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N2-2-t-nh-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/N3-3-T-nh-SD-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N3-3-T-nh-SD-SMP-hp index b3100f69c8cf..b3100f69c8cf 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/N3-3-T-nh-SD-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N3-3-T-nh-SD-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/N4-A-t-NH-sd-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N4-A-t-NH-sd-SMP-HP index c56b44530725..c56b44530725 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/N4-A-t-NH-sd-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N4-A-t-NH-sd-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/N5-U-T-NH-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N5-U-T-NH-sd-SMP-hp index 90d924fea9e9..90d924fea9e9 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/N5-U-T-NH-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/N5-U-T-NH-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/NT1-nh b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/NT1-nh index 023f312a931c..023f312a931c 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/NT1-nh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/NT1-nh | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/NT3-NH b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/NT3-NH index 6fd0235dae73..6fd0235dae73 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/NT3-NH +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/NT3-NH | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/P1-S-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P1-S-T-NH-SD-SMP-HP index f72402d7c13d..f72402d7c13d 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/P1-S-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P1-S-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/P2-2-t-nh-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P2-2-t-nh-sd-SMP-hp index 0f3b667d2a9f..0f3b667d2a9f 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/P2-2-t-nh-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P2-2-t-nh-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/P3-3-T-nh-SD-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P3-3-T-nh-SD-SMP-hp index b035e141bf2a..b035e141bf2a 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/P3-3-T-nh-SD-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P3-3-T-nh-SD-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/P4-A-t-NH-sd-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P4-A-t-NH-sd-SMP-HP index 3ccf6a9447f5..3ccf6a9447f5 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/P4-A-t-NH-sd-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P4-A-t-NH-sd-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/P5-U-T-NH-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P5-U-T-NH-sd-SMP-hp index ef624ce73d8e..ef624ce73d8e 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/P5-U-T-NH-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/P5-U-T-NH-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/PT1-nh b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/PT1-nh index e3361c3894a1..e3361c3894a1 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/PT1-nh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/PT1-nh | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/PT2-NH b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/PT2-NH index 64abfc3b4d94..64abfc3b4d94 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/PT2-NH +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/PT2-NH | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v0.0/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/ver_functions.sh index e8052539af54..5ace37a89780 100644 --- a/tools/testing/selftests/rcutorture/configs/v0.0/ver_functions.sh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v0.0/ver_functions.sh | |||
@@ -20,16 +20,14 @@ | |||
20 | # | 20 | # |
21 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 21 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> |
22 | 22 | ||
23 | # rcutorture_param_n_barrier_cbs bootparam-string | 23 | # per_version_boot_params bootparam-string config-file seconds |
24 | # | 24 | # |
25 | # Adds n_barrier_cbs rcutorture module parameter to kernels having it. | 25 | # Adds per-version torture-module parameters to kernels supporting them. |
26 | rcutorture_param_n_barrier_cbs () { | 26 | # Which old kernels do not. |
27 | echo $1 | 27 | per_version_boot_params () { |
28 | } | 28 | echo rcutorture.stat_interval=15 \ |
29 | 29 | rcutorture.shutdown_secs=$3 \ | |
30 | # rcutorture_param_onoff bootparam-string config-file | 30 | rcutorture.rcutorture_runnable=1 \ |
31 | # | 31 | rcutorture.test_no_idle_hz=1 \ |
32 | # Adds onoff rcutorture module parameters to kernels having it. | 32 | rcutorture.verbose=1 |
33 | rcutorture_param_onoff () { | ||
34 | echo $1 | ||
35 | } | 33 | } |
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/CFLIST b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/CFLIST index da4cbc668f2a..da4cbc668f2a 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/CFLIST +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/CFLIST | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/N1-S-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N1-S-T-NH-SD-SMP-HP index d81e11d280aa..d81e11d280aa 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/N1-S-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N1-S-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/N2-2-t-nh-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N2-2-t-nh-sd-SMP-hp index 02e418572b1b..02e418572b1b 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/N2-2-t-nh-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N2-2-t-nh-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/N3-3-T-nh-SD-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N3-3-T-nh-SD-SMP-hp index b3100f69c8cf..b3100f69c8cf 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/N3-3-T-nh-SD-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N3-3-T-nh-SD-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/N4-A-t-NH-sd-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N4-A-t-NH-sd-SMP-HP index c56b44530725..c56b44530725 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/N4-A-t-NH-sd-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N4-A-t-NH-sd-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/N5-U-T-NH-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N5-U-T-NH-sd-SMP-hp index 90d924fea9e9..90d924fea9e9 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/N5-U-T-NH-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N5-U-T-NH-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/N6---t-nh-SD-smp-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N6---t-nh-SD-smp-hp index 0ccc36d72738..0ccc36d72738 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/N6---t-nh-SD-smp-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N6---t-nh-SD-smp-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/N7-4-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N7-4-T-NH-SD-SMP-HP index 3f640cf84973..3f640cf84973 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/N7-4-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N7-4-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/N8-2-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N8-2-T-NH-SD-SMP-HP index 285da2dd8ac3..285da2dd8ac3 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/N8-2-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/N8-2-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/NT1-nh b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/NT1-nh index 023f312a931c..023f312a931c 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/NT1-nh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/NT1-nh | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/NT3-NH b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/NT3-NH index 6fd0235dae73..6fd0235dae73 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/NT3-NH +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/NT3-NH | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P1-S-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P1-S-T-NH-SD-SMP-HP index 9647c44cf4b7..9647c44cf4b7 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P1-S-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P1-S-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P2-2-t-nh-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P2-2-t-nh-sd-SMP-hp index 0f3b667d2a9f..0f3b667d2a9f 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P2-2-t-nh-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P2-2-t-nh-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P3-3-T-nh-SD-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P3-3-T-nh-SD-SMP-hp index b035e141bf2a..b035e141bf2a 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P3-3-T-nh-SD-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P3-3-T-nh-SD-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P4-A-t-NH-sd-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P4-A-t-NH-sd-SMP-HP index 3ccf6a9447f5..3ccf6a9447f5 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P4-A-t-NH-sd-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P4-A-t-NH-sd-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P5-U-T-NH-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P5-U-T-NH-sd-SMP-hp index ef624ce73d8e..ef624ce73d8e 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P5-U-T-NH-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P5-U-T-NH-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P6---t-nh-SD-smp-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P6---t-nh-SD-smp-hp index f4c9175828bf..f4c9175828bf 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P6---t-nh-SD-smp-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P6---t-nh-SD-smp-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-HP index 77a8c5b75763..77a8c5b75763 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-HP-all b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-HP-all index 0eecebc6e95f..0eecebc6e95f 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-HP-all +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-HP-all | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-HP-none b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-HP-none index 0eecebc6e95f..0eecebc6e95f 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-HP-none +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-HP-none | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-hp index 588bc70420cd..588bc70420cd 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/P7-4-T-NH-SD-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/P7-4-T-NH-SD-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/PT1-nh b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/PT1-nh index e3361c3894a1..e3361c3894a1 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/PT1-nh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/PT1-nh | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.12/PT2-NH b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/PT2-NH index 64abfc3b4d94..64abfc3b4d94 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.12/PT2-NH +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.12/PT2-NH | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/CFLIST b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/CFLIST index 18223947bbcb..18223947bbcb 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/CFLIST +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/CFLIST | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/N1-S-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N1-S-T-NH-SD-SMP-HP index d81e11d280aa..d81e11d280aa 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/N1-S-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N1-S-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/N2-2-t-nh-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N2-2-t-nh-sd-SMP-hp index 02e418572b1b..02e418572b1b 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/N2-2-t-nh-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N2-2-t-nh-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/N3-3-T-nh-SD-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N3-3-T-nh-SD-SMP-hp index b3100f69c8cf..b3100f69c8cf 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/N3-3-T-nh-SD-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N3-3-T-nh-SD-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/N4-A-t-NH-sd-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N4-A-t-NH-sd-SMP-HP index c56b44530725..c56b44530725 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/N4-A-t-NH-sd-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N4-A-t-NH-sd-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/N5-U-T-NH-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N5-U-T-NH-sd-SMP-hp index 90d924fea9e9..90d924fea9e9 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/N5-U-T-NH-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/N5-U-T-NH-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/NT1-nh b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/NT1-nh index 023f312a931c..023f312a931c 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/NT1-nh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/NT1-nh | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/NT3-NH b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/NT3-NH index 6fd0235dae73..6fd0235dae73 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/NT3-NH +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/NT3-NH | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/P1-S-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P1-S-T-NH-SD-SMP-HP index 9647c44cf4b7..9647c44cf4b7 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/P1-S-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P1-S-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/P2-2-t-nh-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P2-2-t-nh-sd-SMP-hp index 0f3b667d2a9f..0f3b667d2a9f 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/P2-2-t-nh-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P2-2-t-nh-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/P3-3-T-nh-SD-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P3-3-T-nh-SD-SMP-hp index b035e141bf2a..b035e141bf2a 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/P3-3-T-nh-SD-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P3-3-T-nh-SD-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/P4-A-t-NH-sd-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P4-A-t-NH-sd-SMP-HP index 3ccf6a9447f5..3ccf6a9447f5 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/P4-A-t-NH-sd-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P4-A-t-NH-sd-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/P5-U-T-NH-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P5-U-T-NH-sd-SMP-hp index ef624ce73d8e..ef624ce73d8e 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/P5-U-T-NH-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/P5-U-T-NH-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/PT1-nh b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/PT1-nh index e3361c3894a1..e3361c3894a1 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/PT1-nh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/PT1-nh | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/PT2-NH b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/PT2-NH index 64abfc3b4d94..64abfc3b4d94 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/PT2-NH +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/PT2-NH | |||
diff --git a/tools/testing/selftests/rcutorture/configs/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/ver_functions.sh index 5e40eadea777..bae55692ce6e 100644 --- a/tools/testing/selftests/rcutorture/configs/ver_functions.sh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.3/ver_functions.sh | |||
@@ -20,18 +20,6 @@ | |||
20 | # | 20 | # |
21 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 21 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> |
22 | 22 | ||
23 | # rcutorture_param_n_barrier_cbs bootparam-string | ||
24 | # | ||
25 | # Adds n_barrier_cbs rcutorture module parameter to kernels having it. | ||
26 | rcutorture_param_n_barrier_cbs () { | ||
27 | if echo $1 | grep -q "rcutorture\.n_barrier_cbs" | ||
28 | then | ||
29 | echo $1 | ||
30 | else | ||
31 | echo $1 rcutorture.n_barrier_cbs=4 | ||
32 | fi | ||
33 | } | ||
34 | |||
35 | # rcutorture_param_onoff bootparam-string config-file | 23 | # rcutorture_param_onoff bootparam-string config-file |
36 | # | 24 | # |
37 | # Adds onoff rcutorture module parameters to kernels having it. | 25 | # Adds onoff rcutorture module parameters to kernels having it. |
@@ -39,8 +27,18 @@ rcutorture_param_onoff () { | |||
39 | if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" | 27 | if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" |
40 | then | 28 | then |
41 | echo CPU-hotplug kernel, adding rcutorture onoff. 1>&2 | 29 | echo CPU-hotplug kernel, adding rcutorture onoff. 1>&2 |
42 | echo $1 rcutorture.onoff_interval=3 rcutorture.onoff_holdoff=30 | 30 | echo rcutorture.onoff_interval=3 rcutorture.onoff_holdoff=30 |
43 | else | ||
44 | echo $1 | ||
45 | fi | 31 | fi |
46 | } | 32 | } |
33 | |||
34 | # per_version_boot_params bootparam-string config-file seconds | ||
35 | # | ||
36 | # Adds per-version torture-module parameters to kernels supporting them. | ||
37 | per_version_boot_params () { | ||
38 | echo $1 `rcutorture_param_onoff "$1" "$2"` \ | ||
39 | rcutorture.stat_interval=15 \ | ||
40 | rcutorture.shutdown_secs=$3 \ | ||
41 | rcutorture.rcutorture_runnable=1 \ | ||
42 | rcutorture.test_no_idle_hz=1 \ | ||
43 | rcutorture.verbose=1 | ||
44 | } | ||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/CFLIST b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/CFLIST index 18223947bbcb..18223947bbcb 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/CFLIST +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/CFLIST | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/N1-S-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N1-S-T-NH-SD-SMP-HP index d81e11d280aa..d81e11d280aa 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/N1-S-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N1-S-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/N2-2-t-nh-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N2-2-t-nh-sd-SMP-hp index 02e418572b1b..02e418572b1b 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/N2-2-t-nh-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N2-2-t-nh-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/N3-3-T-nh-SD-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N3-3-T-nh-SD-SMP-hp index b3100f69c8cf..b3100f69c8cf 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/N3-3-T-nh-SD-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N3-3-T-nh-SD-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/N4-A-t-NH-sd-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N4-A-t-NH-sd-SMP-HP index c56b44530725..c56b44530725 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/N4-A-t-NH-sd-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N4-A-t-NH-sd-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/N5-U-T-NH-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N5-U-T-NH-sd-SMP-hp index 90d924fea9e9..90d924fea9e9 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/N5-U-T-NH-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/N5-U-T-NH-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/NT1-nh b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/NT1-nh index 023f312a931c..023f312a931c 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/NT1-nh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/NT1-nh | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/NT3-NH b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/NT3-NH index 6fd0235dae73..6fd0235dae73 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/NT3-NH +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/NT3-NH | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/P1-S-T-NH-SD-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P1-S-T-NH-SD-SMP-HP index 9647c44cf4b7..9647c44cf4b7 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/P1-S-T-NH-SD-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P1-S-T-NH-SD-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/P2-2-t-nh-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P2-2-t-nh-sd-SMP-hp index 0f3b667d2a9f..0f3b667d2a9f 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/P2-2-t-nh-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P2-2-t-nh-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/P3-3-T-nh-SD-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P3-3-T-nh-SD-SMP-hp index b035e141bf2a..b035e141bf2a 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/P3-3-T-nh-SD-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P3-3-T-nh-SD-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/P4-A-t-NH-sd-SMP-HP b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P4-A-t-NH-sd-SMP-HP index 3ccf6a9447f5..3ccf6a9447f5 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/P4-A-t-NH-sd-SMP-HP +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P4-A-t-NH-sd-SMP-HP | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/P5-U-T-NH-sd-SMP-hp b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P5-U-T-NH-sd-SMP-hp index ef624ce73d8e..ef624ce73d8e 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/P5-U-T-NH-sd-SMP-hp +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/P5-U-T-NH-sd-SMP-hp | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/PT1-nh b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/PT1-nh index e3361c3894a1..e3361c3894a1 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/PT1-nh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/PT1-nh | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/PT2-NH b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/PT2-NH index 64abfc3b4d94..64abfc3b4d94 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/PT2-NH +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/PT2-NH | |||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.5/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/ver_functions.sh index 6a5f13aab44d..8977d8d31b19 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.5/ver_functions.sh +++ b/tools/testing/selftests/rcutorture/configs/rcu/v3.5/ver_functions.sh | |||
@@ -26,9 +26,9 @@ | |||
26 | rcutorture_param_n_barrier_cbs () { | 26 | rcutorture_param_n_barrier_cbs () { |
27 | if echo $1 | grep -q "rcutorture\.n_barrier_cbs" | 27 | if echo $1 | grep -q "rcutorture\.n_barrier_cbs" |
28 | then | 28 | then |
29 | echo $1 | 29 | : |
30 | else | 30 | else |
31 | echo $1 rcutorture.n_barrier_cbs=4 | 31 | echo rcutorture.n_barrier_cbs=4 |
32 | fi | 32 | fi |
33 | } | 33 | } |
34 | 34 | ||
@@ -38,9 +38,20 @@ rcutorture_param_n_barrier_cbs () { | |||
38 | rcutorture_param_onoff () { | 38 | rcutorture_param_onoff () { |
39 | if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" | 39 | if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" |
40 | then | 40 | then |
41 | echo CPU-hotplug kernel, adding rcutorture onoff. | 41 | echo CPU-hotplug kernel, adding rcutorture onoff. 1>&2 |
42 | echo $1 rcutorture.onoff_interval=3 rcutorture.onoff_holdoff=30 | 42 | echo rcutorture.onoff_interval=3 rcutorture.onoff_holdoff=30 |
43 | else | ||
44 | echo $1 | ||
45 | fi | 43 | fi |
46 | } | 44 | } |
45 | |||
46 | # per_version_boot_params bootparam-string config-file seconds | ||
47 | # | ||
48 | # Adds per-version torture-module parameters to kernels supporting them. | ||
49 | per_version_boot_params () { | ||
50 | echo $1 `rcutorture_param_onoff "$1" "$2"` \ | ||
51 | `rcutorture_param_n_barrier_cbs "$1"` \ | ||
52 | rcutorture.stat_interval=15 \ | ||
53 | rcutorture.shutdown_secs=$3 \ | ||
54 | rcutorture.rcutorture_runnable=1 \ | ||
55 | rcutorture.test_no_idle_hz=1 \ | ||
56 | rcutorture.verbose=1 | ||
57 | } | ||
diff --git a/tools/testing/selftests/rcutorture/configs/v3.3/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh index c37432f3572c..8977d8d31b19 100644 --- a/tools/testing/selftests/rcutorture/configs/v3.3/ver_functions.sh +++ b/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh | |||
@@ -24,7 +24,12 @@ | |||
24 | # | 24 | # |
25 | # Adds n_barrier_cbs rcutorture module parameter to kernels having it. | 25 | # Adds n_barrier_cbs rcutorture module parameter to kernels having it. |
26 | rcutorture_param_n_barrier_cbs () { | 26 | rcutorture_param_n_barrier_cbs () { |
27 | echo $1 | 27 | if echo $1 | grep -q "rcutorture\.n_barrier_cbs" |
28 | then | ||
29 | : | ||
30 | else | ||
31 | echo rcutorture.n_barrier_cbs=4 | ||
32 | fi | ||
28 | } | 33 | } |
29 | 34 | ||
30 | # rcutorture_param_onoff bootparam-string config-file | 35 | # rcutorture_param_onoff bootparam-string config-file |
@@ -33,9 +38,20 @@ rcutorture_param_n_barrier_cbs () { | |||
33 | rcutorture_param_onoff () { | 38 | rcutorture_param_onoff () { |
34 | if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" | 39 | if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" |
35 | then | 40 | then |
36 | echo CPU-hotplug kernel, adding rcutorture onoff. | 41 | echo CPU-hotplug kernel, adding rcutorture onoff. 1>&2 |
37 | echo $1 rcutorture.onoff_interval=3 rcutorture.onoff_holdoff=30 | 42 | echo rcutorture.onoff_interval=3 rcutorture.onoff_holdoff=30 |
38 | else | ||
39 | echo $1 | ||
40 | fi | 43 | fi |
41 | } | 44 | } |
45 | |||
46 | # per_version_boot_params bootparam-string config-file seconds | ||
47 | # | ||
48 | # Adds per-version torture-module parameters to kernels supporting them. | ||
49 | per_version_boot_params () { | ||
50 | echo $1 `rcutorture_param_onoff "$1" "$2"` \ | ||
51 | `rcutorture_param_n_barrier_cbs "$1"` \ | ||
52 | rcutorture.stat_interval=15 \ | ||
53 | rcutorture.shutdown_secs=$3 \ | ||
54 | rcutorture.rcutorture_runnable=1 \ | ||
55 | rcutorture.test_no_idle_hz=1 \ | ||
56 | rcutorture.verbose=1 | ||
57 | } | ||
diff --git a/tools/testing/selftests/rcutorture/doc/TREE_RCU-Kconfig.txt b/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt index adbb76cffb49..adbb76cffb49 100644 --- a/tools/testing/selftests/rcutorture/doc/TREE_RCU-Kconfig.txt +++ b/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt | |||