1 #!/bin/bash 1 #!/bin/bash 2 # SPDX-License-Identifier: GPL-2.0 2 # SPDX-License-Identifier: GPL-2.0 3 3 4 SYSFS= 4 SYSFS= 5 # Kselftest framework requirement - SKIP code 5 # Kselftest framework requirement - SKIP code is 4. 6 ksft_skip=4 6 ksft_skip=4 7 retval=0 << 8 7 9 prerequisite() 8 prerequisite() 10 { 9 { 11 msg="skip all tests:" 10 msg="skip all tests:" 12 11 13 if [ $UID != 0 ]; then 12 if [ $UID != 0 ]; then 14 echo $msg must be run as root 13 echo $msg must be run as root >&2 15 exit $ksft_skip 14 exit $ksft_skip 16 fi 15 fi 17 16 18 taskset -p 01 $$ 17 taskset -p 01 $$ 19 18 20 SYSFS=`mount -t sysfs | head -1 | awk 19 SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` 21 20 22 if [ ! -d "$SYSFS" ]; then 21 if [ ! -d "$SYSFS" ]; then 23 echo $msg sysfs is not mounted 22 echo $msg sysfs is not mounted >&2 24 exit $ksft_skip 23 exit $ksft_skip 25 fi 24 fi 26 25 27 if ! ls $SYSFS/devices/system/cpu/cpu* 26 if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then 28 echo $msg cpu hotplug is not s 27 echo $msg cpu hotplug is not supported >&2 29 exit $ksft_skip 28 exit $ksft_skip 30 fi 29 fi 31 30 32 echo "CPU online/offline summary:" 31 echo "CPU online/offline summary:" 33 online_cpus=`cat $SYSFS/devices/system 32 online_cpus=`cat $SYSFS/devices/system/cpu/online` 34 online_max=${online_cpus##*-} 33 online_max=${online_cpus##*-} 35 34 36 if [[ "$online_cpus" = "$online_max" ] 35 if [[ "$online_cpus" = "$online_max" ]]; then 37 echo "$msg: since there is onl 36 echo "$msg: since there is only one cpu: $online_cpus" 38 exit $ksft_skip 37 exit $ksft_skip 39 fi 38 fi 40 39 41 present_cpus=`cat $SYSFS/devices/syste << 42 present_max=${present_cpus##*-} << 43 echo "present_cpus = $present_cpus pre << 44 << 45 echo -e "\t Cpus in online state: $onl 40 echo -e "\t Cpus in online state: $online_cpus" 46 41 47 offline_cpus=`cat $SYSFS/devices/syste 42 offline_cpus=`cat $SYSFS/devices/system/cpu/offline` 48 if [[ "a$offline_cpus" = "a" ]]; then 43 if [[ "a$offline_cpus" = "a" ]]; then 49 offline_cpus=0 44 offline_cpus=0 50 else 45 else 51 offline_max=${offline_cpus##*- 46 offline_max=${offline_cpus##*-} 52 fi 47 fi 53 echo -e "\t Cpus in offline state: $of 48 echo -e "\t Cpus in offline state: $offline_cpus" 54 } 49 } 55 50 56 # 51 # 57 # list all hot-pluggable CPUs 52 # list all hot-pluggable CPUs 58 # 53 # 59 hotpluggable_cpus() 54 hotpluggable_cpus() 60 { 55 { 61 local state=${1:-.\*} 56 local state=${1:-.\*} 62 57 63 for cpu in $SYSFS/devices/system/cpu/c 58 for cpu in $SYSFS/devices/system/cpu/cpu*; do 64 if [ -f $cpu/online ] && grep 59 if [ -f $cpu/online ] && grep -q $state $cpu/online; then 65 echo ${cpu##/*/cpu} 60 echo ${cpu##/*/cpu} 66 fi 61 fi 67 done 62 done 68 } 63 } 69 64 70 hotplaggable_offline_cpus() 65 hotplaggable_offline_cpus() 71 { 66 { 72 hotpluggable_cpus 0 67 hotpluggable_cpus 0 73 } 68 } 74 69 75 hotpluggable_online_cpus() 70 hotpluggable_online_cpus() 76 { 71 { 77 hotpluggable_cpus 1 72 hotpluggable_cpus 1 78 } 73 } 79 74 80 cpu_is_online() 75 cpu_is_online() 81 { 76 { 82 grep -q 1 $SYSFS/devices/system/cpu/cp 77 grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online 83 } 78 } 84 79 85 cpu_is_offline() 80 cpu_is_offline() 86 { 81 { 87 grep -q 0 $SYSFS/devices/system/cpu/cp 82 grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online 88 } 83 } 89 84 90 online_cpu() 85 online_cpu() 91 { 86 { 92 echo 1 > $SYSFS/devices/system/cpu/cpu 87 echo 1 > $SYSFS/devices/system/cpu/cpu$1/online 93 } 88 } 94 89 95 offline_cpu() 90 offline_cpu() 96 { 91 { 97 echo 0 > $SYSFS/devices/system/cpu/cpu 92 echo 0 > $SYSFS/devices/system/cpu/cpu$1/online 98 } 93 } 99 94 100 online_cpu_expect_success() 95 online_cpu_expect_success() 101 { 96 { 102 local cpu=$1 97 local cpu=$1 103 98 104 if ! online_cpu $cpu; then 99 if ! online_cpu $cpu; then 105 echo $FUNCNAME $cpu: unexpecte 100 echo $FUNCNAME $cpu: unexpected fail >&2 106 retval=1 !! 101 exit 1 107 elif ! cpu_is_online $cpu; then 102 elif ! cpu_is_online $cpu; then 108 echo $FUNCNAME $cpu: unexpecte 103 echo $FUNCNAME $cpu: unexpected offline >&2 109 retval=1 !! 104 exit 1 110 fi 105 fi 111 } 106 } 112 107 113 online_cpu_expect_fail() 108 online_cpu_expect_fail() 114 { 109 { 115 local cpu=$1 110 local cpu=$1 116 111 117 if online_cpu $cpu 2> /dev/null; then 112 if online_cpu $cpu 2> /dev/null; then 118 echo $FUNCNAME $cpu: unexpecte 113 echo $FUNCNAME $cpu: unexpected success >&2 119 retval=1 !! 114 exit 1 120 elif ! cpu_is_offline $cpu; then 115 elif ! cpu_is_offline $cpu; then 121 echo $FUNCNAME $cpu: unexpecte 116 echo $FUNCNAME $cpu: unexpected online >&2 122 retval=1 !! 117 exit 1 123 fi 118 fi 124 } 119 } 125 120 126 offline_cpu_expect_success() 121 offline_cpu_expect_success() 127 { 122 { 128 local cpu=$1 123 local cpu=$1 129 124 130 if ! offline_cpu $cpu; then 125 if ! offline_cpu $cpu; then 131 echo $FUNCNAME $cpu: unexpecte 126 echo $FUNCNAME $cpu: unexpected fail >&2 132 retval=1 !! 127 exit 1 133 elif ! cpu_is_offline $cpu; then 128 elif ! cpu_is_offline $cpu; then 134 echo $FUNCNAME $cpu: unexpecte 129 echo $FUNCNAME $cpu: unexpected offline >&2 135 retval=1 !! 130 exit 1 136 fi 131 fi 137 } 132 } 138 133 139 offline_cpu_expect_fail() 134 offline_cpu_expect_fail() 140 { 135 { 141 local cpu=$1 136 local cpu=$1 142 137 143 if offline_cpu $cpu 2> /dev/null; then 138 if offline_cpu $cpu 2> /dev/null; then 144 echo $FUNCNAME $cpu: unexpecte 139 echo $FUNCNAME $cpu: unexpected success >&2 145 retval=1 !! 140 exit 1 146 elif ! cpu_is_online $cpu; then 141 elif ! cpu_is_online $cpu; then 147 echo $FUNCNAME $cpu: unexpecte 142 echo $FUNCNAME $cpu: unexpected offline >&2 148 retval=1 !! 143 exit 1 149 fi 144 fi 150 } 145 } 151 146 152 online_all_hot_pluggable_cpus() !! 147 error=-12 153 { << 154 for cpu in `hotplaggable_offline_cpus` << 155 online_cpu_expect_success $cpu << 156 done << 157 } << 158 << 159 offline_all_hot_pluggable_cpus() << 160 { << 161 local reserve_cpu=$online_max << 162 for cpu in `hotpluggable_online_cpus`; << 163 # Reserve one cpu oneline at l << 164 if [ $cpu -eq $reserve_cpu ];t << 165 continue << 166 fi << 167 offline_cpu_expect_success $cp << 168 done << 169 } << 170 << 171 allcpus=0 148 allcpus=0 >> 149 priority=0 172 online_cpus=0 150 online_cpus=0 173 online_max=0 151 online_max=0 174 offline_cpus=0 152 offline_cpus=0 175 offline_max=0 153 offline_max=0 176 present_cpus=0 << 177 present_max=0 << 178 154 179 while getopts ah opt; do !! 155 while getopts e:ahp: opt; do 180 case $opt in 156 case $opt in >> 157 e) >> 158 error=$OPTARG >> 159 ;; 181 a) 160 a) 182 allcpus=1 161 allcpus=1 183 ;; 162 ;; 184 h) 163 h) 185 echo "Usage $0 [ -a ]" !! 164 echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]" 186 echo -e "\t default offline on 165 echo -e "\t default offline one cpu" 187 echo -e "\t run with -a option 166 echo -e "\t run with -a option to offline all cpus" 188 exit 167 exit 189 ;; 168 ;; >> 169 p) >> 170 priority=$OPTARG >> 171 ;; 190 esac 172 esac 191 done 173 done 192 174 >> 175 if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then >> 176 echo "error code must be -4095 <= errno < 0" >&2 >> 177 exit 1 >> 178 fi >> 179 193 prerequisite 180 prerequisite 194 181 195 # 182 # 196 # Safe test (default) - offline and online one 183 # Safe test (default) - offline and online one cpu 197 # 184 # 198 if [ $allcpus -eq 0 ]; then 185 if [ $allcpus -eq 0 ]; then 199 echo "Limited scope test: one hotplug 186 echo "Limited scope test: one hotplug cpu" 200 echo -e "\t (leaves cpu in the origina 187 echo -e "\t (leaves cpu in the original state):" 201 echo -e "\t online to offline to onlin 188 echo -e "\t online to offline to online: cpu $online_max" 202 offline_cpu_expect_success $online_max 189 offline_cpu_expect_success $online_max 203 online_cpu_expect_success $online_max 190 online_cpu_expect_success $online_max 204 191 205 if [[ $offline_cpus -gt 0 ]]; then 192 if [[ $offline_cpus -gt 0 ]]; then 206 echo -e "\t online to offline !! 193 echo -e "\t offline to online to offline: cpu $offline_max" 207 online_cpu_expect_success $pre !! 194 online_cpu_expect_success $offline_max 208 offline_cpu_expect_success $pr !! 195 offline_cpu_expect_success $offline_max 209 online_cpu $present_max << 210 fi 196 fi 211 exit $retval !! 197 exit 0 212 else 198 else 213 echo "Full scope test: all hotplug cpu 199 echo "Full scope test: all hotplug cpus" 214 echo -e "\t online all offline cpus" 200 echo -e "\t online all offline cpus" 215 echo -e "\t offline all online cpus" 201 echo -e "\t offline all online cpus" 216 echo -e "\t online all offline cpus" 202 echo -e "\t online all offline cpus" 217 fi 203 fi 218 204 219 online_all_hot_pluggable_cpus !! 205 # >> 206 # Online all hot-pluggable CPUs >> 207 # >> 208 for cpu in `hotplaggable_offline_cpus`; do >> 209 online_cpu_expect_success $cpu >> 210 done >> 211 >> 212 # >> 213 # Offline all hot-pluggable CPUs >> 214 # >> 215 for cpu in `hotpluggable_online_cpus`; do >> 216 offline_cpu_expect_success $cpu >> 217 done >> 218 >> 219 # >> 220 # Online all hot-pluggable CPUs again >> 221 # >> 222 for cpu in `hotplaggable_offline_cpus`; do >> 223 online_cpu_expect_success $cpu >> 224 done >> 225 >> 226 # >> 227 # Test with cpu notifier error injection >> 228 # >> 229 >> 230 DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` >> 231 NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu >> 232 >> 233 prerequisite_extra() >> 234 { >> 235 msg="skip extra tests:" >> 236 >> 237 /sbin/modprobe -q -r cpu-notifier-error-inject >> 238 /sbin/modprobe -q cpu-notifier-error-inject priority=$priority >> 239 >> 240 if [ ! -d "$DEBUGFS" ]; then >> 241 echo $msg debugfs is not mounted >&2 >> 242 exit $ksft_skip >> 243 fi >> 244 >> 245 if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then >> 246 echo $msg cpu-notifier-error-inject module is not available >&2 >> 247 exit $ksft_skip >> 248 fi >> 249 } 220 250 221 offline_all_hot_pluggable_cpus !! 251 prerequisite_extra 222 252 223 online_all_hot_pluggable_cpus !! 253 # >> 254 # Offline all hot-pluggable CPUs >> 255 # >> 256 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error >> 257 for cpu in `hotpluggable_online_cpus`; do >> 258 offline_cpu_expect_success $cpu >> 259 done >> 260 >> 261 # >> 262 # Test CPU hot-add error handling (offline => online) >> 263 # >> 264 echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error >> 265 for cpu in `hotplaggable_offline_cpus`; do >> 266 online_cpu_expect_fail $cpu >> 267 done >> 268 >> 269 # >> 270 # Online all hot-pluggable CPUs >> 271 # >> 272 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error >> 273 for cpu in `hotplaggable_offline_cpus`; do >> 274 online_cpu_expect_success $cpu >> 275 done >> 276 >> 277 # >> 278 # Test CPU hot-remove error handling (online => offline) >> 279 # >> 280 echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error >> 281 for cpu in `hotpluggable_online_cpus`; do >> 282 offline_cpu_expect_fail $cpu >> 283 done 224 284 225 exit $retval !! 285 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error >> 286 /sbin/modprobe -q -r cpu-notifier-error-inject
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.