1 #!/bin/sh 2 3 # cpuhotplug_hotplug.sh - Collection of functions for hotplugging 4 # operations. 5 6 # Routines in this library are set up to allow timing to be done 7 # by defining $TIME to a timing command. 8 TIME=${TIME:-""} 9 10 # get_all_irqs() 11 # 12 # Gets list of all available IRQs in the system 13 # 14 get_all_irqs() 15 { 16 echo `egrep [0-9]+: /proc/interrupts | cut -d ':' -f 1` 17 return 18 } 19 20 # migrate_irq(CPU, IRQS) 21 # 22 # Sets the smp_affinity for the list of $IRQS to the given 23 # CPU number 24 # 25 migrate_irq() 26 { 27 CPU=${1#cpu} 28 MASK=$((1<<${CPU})) 29 IRQS=$2 30 for irq in ${IRQS}; do 31 echo $MASK > /proc/irq/${irq}/smp_affinity || \ 32 tst_resm TINFO "It is NOT permitted to change the IRQ $irq smp_affinity" 33 done 34 } 35 36 37 # get_affinity(PID) 38 # 39 # Echos the CPU affinity for the given process ID to stdout 40 # 41 get_affinity_mask() 42 { 43 AFFINITY=`taskset -p ${1}` 44 echo ${AFFINITY} 45 return 46 } 47 48 # set_affinity(PID, CPU) 49 # 50 # Sets the affinity for the given PID to the specified CPU. 51 # 52 set_affinity() 53 { 54 PID="$1" 55 CPU="$2" 56 MASK=$((1<<${CPU_TO_TEST})) 57 `taskset -p ${MASK} ${PID} > /dev/null 2>&1` 58 return $? 59 } 60 61 # online_cpu(CPU) 62 # 63 # Onlines the given CPU. Returns a true value if it was able 64 # to perform the online operation successfully, false otherwise. 65 # 66 # $CPU should either be a specific number like 4, or the cpu name, 67 # as in 'cpu4'. 68 # 69 online_cpu() 70 { 71 CPU=${1#cpu} 72 if [ ! -w /sys/devices/system/cpu/cpu${CPU}/online ]; then 73 return 1 74 fi 75 76 cpu_is_online ${CPU} && return 0 77 78 $TIME echo 1 > /sys/devices/system/cpu/cpu${CPU}/online 79 RC=$? 80 report_timing "Online cpu ${CPU}" 81 return $RC 82 } 83 84 85 # offline_cpu(CPU) 86 # 87 # Offlines the given CPU. Returns a true value if it was able 88 # to perform the offline operation successfully, false otherwise. 89 # 90 offline_cpu() 91 { 92 CPU=${1#cpu} 93 if [ ! -w /sys/devices/system/cpu/cpu${CPU}/online ]; then 94 return 1 95 fi 96 97 ! cpu_is_online ${CPU} && return 0 98 99 $TIME echo 0 > /sys/devices/system/cpu/cpu${CPU}/online 100 RC=$? 101 report_timing "Offline cpu ${CPU}" 102 return $RC 103 } 104 105 # get_cpus_num() 106 # 107 # Prints the number of all available CPUs, regardless of whether they're 108 # currently online or offline. 109 # 110 get_cpus_num() 111 { 112 [ -d /sys/devices/system/cpu/cpu0 ] || return -1 113 NUM=`ls /sys/devices/system/cpu/ \ 114 | grep -c "cpu[0-9][0-9]*"` 115 return $NUM 116 } 117 118 # get_all_cpus() 119 # 120 # Prints a list of all available CPUs, regardless of whether they're 121 # currently online or offline. 122 # 123 # This routine will work even if the CPUs are not hotpluggable, however 124 # it requires you have sysfs enabled in the kernel. 125 # 126 get_all_cpus() 127 { 128 [ -d /sys/devices/system/cpu ] || return 1 129 (cd /sys/devices/system/cpu; ls -d cpu[0-9]*) 130 } 131 132 # get_present_cpus() 133 # 134 # Prints a list of present CPUs, regardless of whether they're 135 # currently online or offline. 136 # 137 get_present_cpus() 138 { 139 local present_mask="/sys/devices/system/cpu/present" 140 local present_cpus="" 141 142 # if sysfs present mask is missing, assume all cpu are present 143 if [ ! -e "$present_mask" ]; then 144 get_all_cpus 145 return 146 fi 147 148 for part in $(cat $present_mask | tr "," " "); do 149 if echo $part | grep -q "-"; then 150 range_low=$(echo $part | cut -d - -f 1) 151 range_high=$(echo $part | cut -d - -f 2) 152 else 153 range_low=$part 154 range_high=$part 155 fi 156 for cpu in $(seq $range_low $range_high); do 157 if [ -e /sys/devices/system/cpu/cpu$cpu ]; then 158 present_cpus="$present_cpus cpu$cpu" 159 fi 160 done 161 done 162 echo $present_cpus 163 } 164 165 # get_present_cpus_num() 166 # 167 # Prints the number of present CPUs 168 # 169 get_present_cpus_num() 170 { 171 echo $(get_present_cpus | wc -w) 172 } 173 174 # get_hotplug_cpus() 175 # 176 # Prints a list of present hotpluggable CPUs, regardless of whether they're 177 # currently online or offline. 178 # 179 get_hotplug_cpus() 180 { 181 local present_cpus="$(get_present_cpus)" 182 local hotplug_cpus="" 183 184 for cpu in $present_cpus; do 185 if [ -e /sys/devices/system/cpu/$cpu/online ]; then 186 hotplug_cpus="$hotplug_cpus $cpu" 187 fi 188 done 189 echo $hotplug_cpus 190 } 191 192 # get_hotplug_cpus_num() 193 # 194 # Prints the number of hotpluggable CPUs 195 # 196 get_hotplug_cpus_num() 197 { 198 echo $(get_hotplug_cpus | wc -w) 199 } 200 201 # get_all_cpu_states() 202 # 203 # Collects the current online/offline state of CPUs in the 204 # system, printing it in a format that can be passed to 205 # set_all_cpu_states() later. 206 # 207 get_all_cpu_states() 208 { 209 echo `cd /sys/devices/system/cpu/ && grep '' */online | \ 210 sed -e 's/\/online//'` 211 return 212 } 213 214 # set_all_cpu_states(STATES) 215 # 216 # Sets all of the CPU states according to STATES, which must be 217 # of the form "cpuX:Y", where X is the CPU number and Y its state. 218 # Each must be on a separate line. 219 # 220 set_all_cpu_states() 221 { 222 for cpu_state in $1; do 223 cpu=`echo $cpu_state | cut -d: -f 1` 224 state=`echo $cpu_state | cut -d: -f 2` 225 if [ $state = 1 ]; then 226 online_cpu $cpu 227 else 228 offline_cpu $cpu 229 fi 230 done 231 } 232 233 234 # get_online_cpus() 235 # 236 # Prints a list of all CPUs currently online. This function only 237 # works if the system's CPUs have hotplug capabilities 238 # 239 get_online_cpus() 240 { 241 echo `cd /sys/devices/system/cpu/ && grep 1 */online | cut -d '/' -f 1` 242 return 243 } 244 245 246 # get_offline_cpus() 247 # 248 # Prints a list of all CPUs currently offline. This function only 249 # works if the system's CPUs have hotplug capabilities 250 # 251 get_offline_cpus() 252 { 253 echo `cd /sys/devices/system/cpu/ && grep 0 */online | cut -d '/' -f 1` 254 return 255 } 256 257 # cpu_is_valid(CPU) 258 # 259 # Checks to see if the given CPU number is available for hotplugging 260 # in the system. Returns 0 if the CPU is available, 1 otherwise. 261 # 262 cpu_is_valid() 263 { 264 CPU=${1#cpu} 265 echo "CPU is $CPU" 266 cat /sys/devices/system/cpu/cpu${CPU}/online > /dev/null 2>&1 267 return $? 268 } 269 270 271 # cpu_is_online(CPU) 272 # 273 # Returns a 0 value if the given CPU number is currently online, 274 # 1 otherwise. This function requires the system's CPUs have 275 # hotplug capabilities. 276 # 277 cpu_is_online() 278 { 279 CPU=${1#cpu} 280 if [ `cat /sys/devices/system/cpu/cpu${CPU}/online` = "1" ]; then 281 return 0 282 else 283 return 1 284 fi 285 } 286