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. 8TIME=${TIME:-""} 9 10# get_all_irqs() 11# 12# Gets list of all available IRQs in the system 13# 14get_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# 25migrate_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# 41get_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# 52set_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# 69online_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# 90offline_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# 110get_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# 126get_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# 137get_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# 169get_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# 179get_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# 196get_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# 207get_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# 220set_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# 239get_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# 251get_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# 262cpu_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# 277cpu_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