Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fault-injection: add selftests for cpu and memory hotplug

This adds two selftests

* tools/testing/selftests/cpu-hotplug/on-off-test.sh is testing script
for CPU hotplug

1. Online all hot-pluggable CPUs
2. Offline all hot-pluggable CPUs
3. Online all hot-pluggable CPUs again
4. Exit if cpu-notifier-error-inject.ko is not available
5. Offline all hot-pluggable CPUs in preparation for testing
6. Test CPU hot-add error handling by injecting notifier errors
7. Online all hot-pluggable CPUs in preparation for testing
8. Test CPU hot-remove error handling by injecting notifier errors

* tools/testing/selftests/memory-hotplug/on-off-test.sh is doing the
similar thing for memory hotplug.

1. Online all hot-pluggable memory
2. Offline 10% of hot-pluggable memory
3. Online all hot-pluggable memory again
4. Exit if memory-notifier-error-inject.ko is not available
5. Offline 10% of hot-pluggable memory in preparation for testing
6. Test memory hot-add error handling by injecting notifier errors
7. Online all hot-pluggable memory in preparation for testing
8. Test memory hot-remove error handling by injecting notifier errors

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Greg KH <greg@kroah.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <michael@ellerman.id.au>
Cc: Dave Jones <davej@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Akinobu Mita and committed by
Linus Torvalds
d89dffa9 08dfb4dd

+464 -1
+1 -1
tools/testing/selftests/Makefile
··· 1 - TARGETS = breakpoints kcmp mqueue vm 1 + TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug 2 2 3 3 all: 4 4 for TARGET in $(TARGETS); do \
+6
tools/testing/selftests/cpu-hotplug/Makefile
··· 1 + all: 2 + 3 + run_tests: 4 + ./on-off-test.sh 5 + 6 + clean:
+221
tools/testing/selftests/cpu-hotplug/on-off-test.sh
··· 1 + #!/bin/bash 2 + 3 + SYSFS= 4 + 5 + prerequisite() 6 + { 7 + msg="skip all tests:" 8 + 9 + if [ $UID != 0 ]; then 10 + echo $msg must be run as root >&2 11 + exit 0 12 + fi 13 + 14 + SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` 15 + 16 + if [ ! -d "$SYSFS" ]; then 17 + echo $msg sysfs is not mounted >&2 18 + exit 0 19 + fi 20 + 21 + if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then 22 + echo $msg cpu hotplug is not supported >&2 23 + exit 0 24 + fi 25 + } 26 + 27 + # 28 + # list all hot-pluggable CPUs 29 + # 30 + hotpluggable_cpus() 31 + { 32 + local state=${1:-.\*} 33 + 34 + for cpu in $SYSFS/devices/system/cpu/cpu*; do 35 + if [ -f $cpu/online ] && grep -q $state $cpu/online; then 36 + echo ${cpu##/*/cpu} 37 + fi 38 + done 39 + } 40 + 41 + hotplaggable_offline_cpus() 42 + { 43 + hotpluggable_cpus 0 44 + } 45 + 46 + hotpluggable_online_cpus() 47 + { 48 + hotpluggable_cpus 1 49 + } 50 + 51 + cpu_is_online() 52 + { 53 + grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online 54 + } 55 + 56 + cpu_is_offline() 57 + { 58 + grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online 59 + } 60 + 61 + online_cpu() 62 + { 63 + echo 1 > $SYSFS/devices/system/cpu/cpu$1/online 64 + } 65 + 66 + offline_cpu() 67 + { 68 + echo 0 > $SYSFS/devices/system/cpu/cpu$1/online 69 + } 70 + 71 + online_cpu_expect_success() 72 + { 73 + local cpu=$1 74 + 75 + if ! online_cpu $cpu; then 76 + echo $FUNCNAME $cpu: unexpected fail >&2 77 + elif ! cpu_is_online $cpu; then 78 + echo $FUNCNAME $cpu: unexpected offline >&2 79 + fi 80 + } 81 + 82 + online_cpu_expect_fail() 83 + { 84 + local cpu=$1 85 + 86 + if online_cpu $cpu 2> /dev/null; then 87 + echo $FUNCNAME $cpu: unexpected success >&2 88 + elif ! cpu_is_offline $cpu; then 89 + echo $FUNCNAME $cpu: unexpected online >&2 90 + fi 91 + } 92 + 93 + offline_cpu_expect_success() 94 + { 95 + local cpu=$1 96 + 97 + if ! offline_cpu $cpu; then 98 + echo $FUNCNAME $cpu: unexpected fail >&2 99 + elif ! cpu_is_offline $cpu; then 100 + echo $FUNCNAME $cpu: unexpected offline >&2 101 + fi 102 + } 103 + 104 + offline_cpu_expect_fail() 105 + { 106 + local cpu=$1 107 + 108 + if offline_cpu $cpu 2> /dev/null; then 109 + echo $FUNCNAME $cpu: unexpected success >&2 110 + elif ! cpu_is_online $cpu; then 111 + echo $FUNCNAME $cpu: unexpected offline >&2 112 + fi 113 + } 114 + 115 + error=-12 116 + priority=0 117 + 118 + while getopts e:hp: opt; do 119 + case $opt in 120 + e) 121 + error=$OPTARG 122 + ;; 123 + h) 124 + echo "Usage $0 [ -e errno ] [ -p notifier-priority ]" 125 + exit 126 + ;; 127 + p) 128 + priority=$OPTARG 129 + ;; 130 + esac 131 + done 132 + 133 + if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then 134 + echo "error code must be -4095 <= errno < 0" >&2 135 + exit 1 136 + fi 137 + 138 + prerequisite 139 + 140 + # 141 + # Online all hot-pluggable CPUs 142 + # 143 + for cpu in `hotplaggable_offline_cpus`; do 144 + online_cpu_expect_success $cpu 145 + done 146 + 147 + # 148 + # Offline all hot-pluggable CPUs 149 + # 150 + for cpu in `hotpluggable_online_cpus`; do 151 + offline_cpu_expect_success $cpu 152 + done 153 + 154 + # 155 + # Online all hot-pluggable CPUs again 156 + # 157 + for cpu in `hotplaggable_offline_cpus`; do 158 + online_cpu_expect_success $cpu 159 + done 160 + 161 + # 162 + # Test with cpu notifier error injection 163 + # 164 + 165 + DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` 166 + NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu 167 + 168 + prerequisite_extra() 169 + { 170 + msg="skip extra tests:" 171 + 172 + /sbin/modprobe -q -r cpu-notifier-error-inject 173 + /sbin/modprobe -q cpu-notifier-error-inject priority=$priority 174 + 175 + if [ ! -d "$DEBUGFS" ]; then 176 + echo $msg debugfs is not mounted >&2 177 + exit 0 178 + fi 179 + 180 + if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then 181 + echo $msg cpu-notifier-error-inject module is not available >&2 182 + exit 0 183 + fi 184 + } 185 + 186 + prerequisite_extra 187 + 188 + # 189 + # Offline all hot-pluggable CPUs 190 + # 191 + echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error 192 + for cpu in `hotpluggable_online_cpus`; do 193 + offline_cpu_expect_success $cpu 194 + done 195 + 196 + # 197 + # Test CPU hot-add error handling (offline => online) 198 + # 199 + echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error 200 + for cpu in `hotplaggable_offline_cpus`; do 201 + online_cpu_expect_fail $cpu 202 + done 203 + 204 + # 205 + # Online all hot-pluggable CPUs 206 + # 207 + echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error 208 + for cpu in `hotplaggable_offline_cpus`; do 209 + online_cpu_expect_success $cpu 210 + done 211 + 212 + # 213 + # Test CPU hot-remove error handling (online => offline) 214 + # 215 + echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error 216 + for cpu in `hotpluggable_online_cpus`; do 217 + offline_cpu_expect_fail $cpu 218 + done 219 + 220 + echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error 221 + /sbin/modprobe -q -r cpu-notifier-error-inject
+6
tools/testing/selftests/memory-hotplug/Makefile
··· 1 + all: 2 + 3 + run_tests: 4 + ./on-off-test.sh 5 + 6 + clean:
+230
tools/testing/selftests/memory-hotplug/on-off-test.sh
··· 1 + #!/bin/bash 2 + 3 + SYSFS= 4 + 5 + prerequisite() 6 + { 7 + msg="skip all tests:" 8 + 9 + if [ $UID != 0 ]; then 10 + echo $msg must be run as root >&2 11 + exit 0 12 + fi 13 + 14 + SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` 15 + 16 + if [ ! -d "$SYSFS" ]; then 17 + echo $msg sysfs is not mounted >&2 18 + exit 0 19 + fi 20 + 21 + if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then 22 + echo $msg memory hotplug is not supported >&2 23 + exit 0 24 + fi 25 + } 26 + 27 + # 28 + # list all hot-pluggable memory 29 + # 30 + hotpluggable_memory() 31 + { 32 + local state=${1:-.\*} 33 + 34 + for memory in $SYSFS/devices/system/memory/memory*; do 35 + if grep -q 1 $memory/removable && 36 + grep -q $state $memory/state; then 37 + echo ${memory##/*/memory} 38 + fi 39 + done 40 + } 41 + 42 + hotplaggable_offline_memory() 43 + { 44 + hotpluggable_memory offline 45 + } 46 + 47 + hotpluggable_online_memory() 48 + { 49 + hotpluggable_memory online 50 + } 51 + 52 + memory_is_online() 53 + { 54 + grep -q online $SYSFS/devices/system/memory/memory$1/state 55 + } 56 + 57 + memory_is_offline() 58 + { 59 + grep -q offline $SYSFS/devices/system/memory/memory$1/state 60 + } 61 + 62 + online_memory() 63 + { 64 + echo online > $SYSFS/devices/system/memory/memory$1/state 65 + } 66 + 67 + offline_memory() 68 + { 69 + echo offline > $SYSFS/devices/system/memory/memory$1/state 70 + } 71 + 72 + online_memory_expect_success() 73 + { 74 + local memory=$1 75 + 76 + if ! online_memory $memory; then 77 + echo $FUNCNAME $memory: unexpected fail >&2 78 + elif ! memory_is_online $memory; then 79 + echo $FUNCNAME $memory: unexpected offline >&2 80 + fi 81 + } 82 + 83 + online_memory_expect_fail() 84 + { 85 + local memory=$1 86 + 87 + if online_memory $memory 2> /dev/null; then 88 + echo $FUNCNAME $memory: unexpected success >&2 89 + elif ! memory_is_offline $memory; then 90 + echo $FUNCNAME $memory: unexpected online >&2 91 + fi 92 + } 93 + 94 + offline_memory_expect_success() 95 + { 96 + local memory=$1 97 + 98 + if ! offline_memory $memory; then 99 + echo $FUNCNAME $memory: unexpected fail >&2 100 + elif ! memory_is_offline $memory; then 101 + echo $FUNCNAME $memory: unexpected offline >&2 102 + fi 103 + } 104 + 105 + offline_memory_expect_fail() 106 + { 107 + local memory=$1 108 + 109 + if offline_memory $memory 2> /dev/null; then 110 + echo $FUNCNAME $memory: unexpected success >&2 111 + elif ! memory_is_online $memory; then 112 + echo $FUNCNAME $memory: unexpected offline >&2 113 + fi 114 + } 115 + 116 + error=-12 117 + priority=0 118 + ratio=10 119 + 120 + while getopts e:hp:r: opt; do 121 + case $opt in 122 + e) 123 + error=$OPTARG 124 + ;; 125 + h) 126 + echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]" 127 + exit 128 + ;; 129 + p) 130 + priority=$OPTARG 131 + ;; 132 + r) 133 + ratio=$OPTARG 134 + ;; 135 + esac 136 + done 137 + 138 + if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then 139 + echo "error code must be -4095 <= errno < 0" >&2 140 + exit 1 141 + fi 142 + 143 + prerequisite 144 + 145 + # 146 + # Online all hot-pluggable memory 147 + # 148 + for memory in `hotplaggable_offline_memory`; do 149 + online_memory_expect_success $memory 150 + done 151 + 152 + # 153 + # Offline $ratio percent of hot-pluggable memory 154 + # 155 + for memory in `hotpluggable_online_memory`; do 156 + if [ $((RANDOM % 100)) -lt $ratio ]; then 157 + offline_memory_expect_success $memory 158 + fi 159 + done 160 + 161 + # 162 + # Online all hot-pluggable memory again 163 + # 164 + for memory in `hotplaggable_offline_memory`; do 165 + online_memory_expect_success $memory 166 + done 167 + 168 + # 169 + # Test with memory notifier error injection 170 + # 171 + 172 + DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` 173 + NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory 174 + 175 + prerequisite_extra() 176 + { 177 + msg="skip extra tests:" 178 + 179 + /sbin/modprobe -q -r memory-notifier-error-inject 180 + /sbin/modprobe -q memory-notifier-error-inject priority=$priority 181 + 182 + if [ ! -d "$DEBUGFS" ]; then 183 + echo $msg debugfs is not mounted >&2 184 + exit 0 185 + fi 186 + 187 + if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then 188 + echo $msg memory-notifier-error-inject module is not available >&2 189 + exit 0 190 + fi 191 + } 192 + 193 + prerequisite_extra 194 + 195 + # 196 + # Offline $ratio percent of hot-pluggable memory 197 + # 198 + echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error 199 + for memory in `hotpluggable_online_memory`; do 200 + if [ $((RANDOM % 100)) -lt $ratio ]; then 201 + offline_memory_expect_success $memory 202 + fi 203 + done 204 + 205 + # 206 + # Test memory hot-add error handling (offline => online) 207 + # 208 + echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error 209 + for memory in `hotplaggable_offline_memory`; do 210 + online_memory_expect_fail $memory 211 + done 212 + 213 + # 214 + # Online all hot-pluggable memory 215 + # 216 + echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error 217 + for memory in `hotplaggable_offline_memory`; do 218 + online_memory_expect_success $memory 219 + done 220 + 221 + # 222 + # Test memory hot-remove error handling (online => offline) 223 + # 224 + echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error 225 + for memory in `hotpluggable_online_memory`; do 226 + offline_memory_expect_fail $memory 227 + done 228 + 229 + echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error 230 + /sbin/modprobe -q -r memory-notifier-error-inject