Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 
0004 SYSFS=
0005 # Kselftest framework requirement - SKIP code is 4.
0006 ksft_skip=4
0007 
0008 prerequisite()
0009 {
0010         msg="skip all tests:"
0011 
0012         if [ $UID != 0 ]; then
0013                 echo $msg must be run as root >&2
0014                 exit $ksft_skip
0015         fi
0016 
0017         taskset -p 01 $$
0018 
0019         SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
0020 
0021         if [ ! -d "$SYSFS" ]; then
0022                 echo $msg sysfs is not mounted >&2
0023                 exit $ksft_skip
0024         fi
0025 
0026         if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then
0027                 echo $msg cpu hotplug is not supported >&2
0028                 exit $ksft_skip
0029         fi
0030 
0031         echo "CPU online/offline summary:"
0032         online_cpus=`cat $SYSFS/devices/system/cpu/online`
0033         online_max=${online_cpus##*-}
0034 
0035         if [[ "$online_cpus" = "$online_max" ]]; then
0036                 echo "$msg: since there is only one cpu: $online_cpus"
0037                 exit $ksft_skip
0038         fi
0039 
0040         present_cpus=`cat $SYSFS/devices/system/cpu/present`
0041         present_max=${present_cpus##*-}
0042         echo "present_cpus = $present_cpus present_max = $present_max"
0043 
0044         echo -e "\t Cpus in online state: $online_cpus"
0045 
0046         offline_cpus=`cat $SYSFS/devices/system/cpu/offline`
0047         if [[ "a$offline_cpus" = "a" ]]; then
0048                 offline_cpus=0
0049         else
0050                 offline_max=${offline_cpus##*-}
0051         fi
0052         echo -e "\t Cpus in offline state: $offline_cpus"
0053 }
0054 
0055 #
0056 # list all hot-pluggable CPUs
0057 #
0058 hotpluggable_cpus()
0059 {
0060         local state=${1:-.\*}
0061 
0062         for cpu in $SYSFS/devices/system/cpu/cpu*; do
0063                 if [ -f $cpu/online ] && grep -q $state $cpu/online; then
0064                         echo ${cpu##/*/cpu}
0065                 fi
0066         done
0067 }
0068 
0069 hotplaggable_offline_cpus()
0070 {
0071         hotpluggable_cpus 0
0072 }
0073 
0074 hotpluggable_online_cpus()
0075 {
0076         hotpluggable_cpus 1
0077 }
0078 
0079 cpu_is_online()
0080 {
0081         grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online
0082 }
0083 
0084 cpu_is_offline()
0085 {
0086         grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online
0087 }
0088 
0089 online_cpu()
0090 {
0091         echo 1 > $SYSFS/devices/system/cpu/cpu$1/online
0092 }
0093 
0094 offline_cpu()
0095 {
0096         echo 0 > $SYSFS/devices/system/cpu/cpu$1/online
0097 }
0098 
0099 online_cpu_expect_success()
0100 {
0101         local cpu=$1
0102 
0103         if ! online_cpu $cpu; then
0104                 echo $FUNCNAME $cpu: unexpected fail >&2
0105                 exit 1
0106         elif ! cpu_is_online $cpu; then
0107                 echo $FUNCNAME $cpu: unexpected offline >&2
0108                 exit 1
0109         fi
0110 }
0111 
0112 online_cpu_expect_fail()
0113 {
0114         local cpu=$1
0115 
0116         if online_cpu $cpu 2> /dev/null; then
0117                 echo $FUNCNAME $cpu: unexpected success >&2
0118                 exit 1
0119         elif ! cpu_is_offline $cpu; then
0120                 echo $FUNCNAME $cpu: unexpected online >&2
0121                 exit 1
0122         fi
0123 }
0124 
0125 offline_cpu_expect_success()
0126 {
0127         local cpu=$1
0128 
0129         if ! offline_cpu $cpu; then
0130                 echo $FUNCNAME $cpu: unexpected fail >&2
0131                 exit 1
0132         elif ! cpu_is_offline $cpu; then
0133                 echo $FUNCNAME $cpu: unexpected offline >&2
0134                 exit 1
0135         fi
0136 }
0137 
0138 offline_cpu_expect_fail()
0139 {
0140         local cpu=$1
0141 
0142         if offline_cpu $cpu 2> /dev/null; then
0143                 echo $FUNCNAME $cpu: unexpected success >&2
0144                 exit 1
0145         elif ! cpu_is_online $cpu; then
0146                 echo $FUNCNAME $cpu: unexpected offline >&2
0147                 exit 1
0148         fi
0149 }
0150 
0151 error=-12
0152 allcpus=0
0153 priority=0
0154 online_cpus=0
0155 online_max=0
0156 offline_cpus=0
0157 offline_max=0
0158 present_cpus=0
0159 present_max=0
0160 
0161 while getopts e:ahp: opt; do
0162         case $opt in
0163         e)
0164                 error=$OPTARG
0165                 ;;
0166         a)
0167                 allcpus=1
0168                 ;;
0169         h)
0170                 echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]"
0171                 echo -e "\t default offline one cpu"
0172                 echo -e "\t run with -a option to offline all cpus"
0173                 exit
0174                 ;;
0175         p)
0176                 priority=$OPTARG
0177                 ;;
0178         esac
0179 done
0180 
0181 if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
0182         echo "error code must be -4095 <= errno < 0" >&2
0183         exit 1
0184 fi
0185 
0186 prerequisite
0187 
0188 #
0189 # Safe test (default) - offline and online one cpu
0190 #
0191 if [ $allcpus -eq 0 ]; then
0192         echo "Limited scope test: one hotplug cpu"
0193         echo -e "\t (leaves cpu in the original state):"
0194         echo -e "\t online to offline to online: cpu $online_max"
0195         offline_cpu_expect_success $online_max
0196         online_cpu_expect_success $online_max
0197 
0198         if [[ $offline_cpus -gt 0 ]]; then
0199                 echo -e "\t offline to online to offline: cpu $present_max"
0200                 online_cpu_expect_success $present_max
0201                 offline_cpu_expect_success $present_max
0202                 online_cpu $present_max
0203         fi
0204         exit 0
0205 else
0206         echo "Full scope test: all hotplug cpus"
0207         echo -e "\t online all offline cpus"
0208         echo -e "\t offline all online cpus"
0209         echo -e "\t online all offline cpus"
0210 fi
0211 
0212 #
0213 # Online all hot-pluggable CPUs
0214 #
0215 for cpu in `hotplaggable_offline_cpus`; do
0216         online_cpu_expect_success $cpu
0217 done
0218 
0219 #
0220 # Offline all hot-pluggable CPUs
0221 #
0222 for cpu in `hotpluggable_online_cpus`; do
0223         offline_cpu_expect_success $cpu
0224 done
0225 
0226 #
0227 # Online all hot-pluggable CPUs again
0228 #
0229 for cpu in `hotplaggable_offline_cpus`; do
0230         online_cpu_expect_success $cpu
0231 done
0232 
0233 #
0234 # Test with cpu notifier error injection
0235 #
0236 
0237 DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
0238 NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu
0239 
0240 prerequisite_extra()
0241 {
0242         msg="skip extra tests:"
0243 
0244         /sbin/modprobe -q -r cpu-notifier-error-inject
0245         /sbin/modprobe -q cpu-notifier-error-inject priority=$priority
0246 
0247         if [ ! -d "$DEBUGFS" ]; then
0248                 echo $msg debugfs is not mounted >&2
0249                 exit $ksft_skip
0250         fi
0251 
0252         if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
0253                 echo $msg cpu-notifier-error-inject module is not available >&2
0254                 exit $ksft_skip
0255         fi
0256 }
0257 
0258 prerequisite_extra
0259 
0260 #
0261 # Offline all hot-pluggable CPUs
0262 #
0263 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
0264 for cpu in `hotpluggable_online_cpus`; do
0265         offline_cpu_expect_success $cpu
0266 done
0267 
0268 #
0269 # Test CPU hot-add error handling (offline => online)
0270 #
0271 echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
0272 for cpu in `hotplaggable_offline_cpus`; do
0273         online_cpu_expect_fail $cpu
0274 done
0275 
0276 #
0277 # Online all hot-pluggable CPUs
0278 #
0279 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
0280 for cpu in `hotplaggable_offline_cpus`; do
0281         online_cpu_expect_success $cpu
0282 done
0283 
0284 #
0285 # Test CPU hot-remove error handling (online => offline)
0286 #
0287 echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
0288 for cpu in `hotpluggable_online_cpus`; do
0289         offline_cpu_expect_fail $cpu
0290 done
0291 
0292 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
0293 /sbin/modprobe -q -r cpu-notifier-error-inject