Home | History | Annotate | Download | only in include
      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