#!/bin/sh # cpuhotplug_hotplug.sh - Collection of functions for hotplugging # operations. # Routines in this library are set up to allow timing to be done # by defining $TIME to a timing command. TIME=${TIME:-""} # get_all_irqs() # # Gets list of all available IRQs in the system # get_all_irqs() { echo `egrep [0-9]+: /proc/interrupts | cut -d ':' -f 1` return } # migrate_irq(CPU, IRQS) # # Sets the smp_affinity for the list of $IRQS to the given # CPU number # migrate_irq() { CPU=${1#cpu} MASK=$((1<<${CPU})) IRQS=$2 for irq in ${IRQS}; do echo $MASK > /proc/irq/${irq}/smp_affinity || \ tst_resm TINFO "It is NOT permitted to change the IRQ $irq smp_affinity" done } # get_affinity(PID) # # Echos the CPU affinity for the given process ID to stdout # get_affinity_mask() { AFFINITY=`taskset -p ${1}` echo ${AFFINITY} return } # set_affinity(PID, CPU) # # Sets the affinity for the given PID to the specified CPU. # set_affinity() { PID="$1" CPU="$2" MASK=$((1<<${CPU_TO_TEST})) `taskset -p ${MASK} ${PID} > /dev/null 2>&1` return $? } # online_cpu(CPU) # # Onlines the given CPU. Returns a true value if it was able # to perform the online operation successfully, false otherwise. # # $CPU should either be a specific number like 4, or the cpu name, # as in 'cpu4'. # online_cpu() { CPU=${1#cpu} if [ ! -w /sys/devices/system/cpu/cpu${CPU}/online ]; then return 1 fi cpu_is_online ${CPU} && return 0 $TIME echo 1 > /sys/devices/system/cpu/cpu${CPU}/online RC=$? report_timing "Online cpu ${CPU}" return $RC } # offline_cpu(CPU) # # Offlines the given CPU. Returns a true value if it was able # to perform the offline operation successfully, false otherwise. # offline_cpu() { CPU=${1#cpu} if [ ! -w /sys/devices/system/cpu/cpu${CPU}/online ]; then return 1 fi ! cpu_is_online ${CPU} && return 0 $TIME echo 0 > /sys/devices/system/cpu/cpu${CPU}/online RC=$? report_timing "Offline cpu ${CPU}" return $RC } # get_cpus_num() # # Prints the number of all available CPUs, regardless of whether they're # currently online or offline. # get_cpus_num() { [ -d /sys/devices/system/cpu/cpu0 ] || return -1 NUM=`ls /sys/devices/system/cpu/ \ | grep -c "cpu[0-9][0-9]*"` return $NUM } # get_all_cpus() # # Prints a list of all available CPUs, regardless of whether they're # currently online or offline. # # This routine will work even if the CPUs are not hotpluggable, however # it requires you have sysfs enabled in the kernel. # get_all_cpus() { [ -d /sys/devices/system/cpu ] || return 1 (cd /sys/devices/system/cpu; ls -d cpu[0-9]*) } # get_present_cpus() # # Prints a list of present CPUs, regardless of whether they're # currently online or offline. # get_present_cpus() { local present_mask="/sys/devices/system/cpu/present" local present_cpus="" # if sysfs present mask is missing, assume all cpu are present if [ ! -e "$present_mask" ]; then get_all_cpus return fi for part in $(cat $present_mask | tr "," " "); do if echo $part | grep -q "-"; then range_low=$(echo $part | cut -d - -f 1) range_high=$(echo $part | cut -d - -f 2) else range_low=$part range_high=$part fi for cpu in $(seq $range_low $range_high); do if [ -e /sys/devices/system/cpu/cpu$cpu ]; then present_cpus="$present_cpus cpu$cpu" fi done done echo $present_cpus } # get_present_cpus_num() # # Prints the number of present CPUs # get_present_cpus_num() { echo $(get_present_cpus | wc -w) } # get_hotplug_cpus() # # Prints a list of present hotpluggable CPUs, regardless of whether they're # currently online or offline. # get_hotplug_cpus() { local present_cpus="$(get_present_cpus)" local hotplug_cpus="" for cpu in $present_cpus; do if [ -e /sys/devices/system/cpu/$cpu/online ]; then hotplug_cpus="$hotplug_cpus $cpu" fi done echo $hotplug_cpus } # get_hotplug_cpus_num() # # Prints the number of hotpluggable CPUs # get_hotplug_cpus_num() { echo $(get_hotplug_cpus | wc -w) } # get_all_cpu_states() # # Collects the current online/offline state of CPUs in the # system, printing it in a format that can be passed to # set_all_cpu_states() later. # get_all_cpu_states() { echo `cd /sys/devices/system/cpu/ && grep '' */online | \ sed -e 's/\/online//'` return } # set_all_cpu_states(STATES) # # Sets all of the CPU states according to STATES, which must be # of the form "cpuX:Y", where X is the CPU number and Y its state. # Each must be on a separate line. # set_all_cpu_states() { for cpu_state in $1; do cpu=`echo $cpu_state | cut -d: -f 1` state=`echo $cpu_state | cut -d: -f 2` if [ $state = 1 ]; then online_cpu $cpu else offline_cpu $cpu fi done } # get_online_cpus() # # Prints a list of all CPUs currently online. This function only # works if the system's CPUs have hotplug capabilities # get_online_cpus() { echo `cd /sys/devices/system/cpu/ && grep 1 */online | cut -d '/' -f 1` return } # get_offline_cpus() # # Prints a list of all CPUs currently offline. This function only # works if the system's CPUs have hotplug capabilities # get_offline_cpus() { echo `cd /sys/devices/system/cpu/ && grep 0 */online | cut -d '/' -f 1` return } # cpu_is_valid(CPU) # # Checks to see if the given CPU number is available for hotplugging # in the system. Returns 0 if the CPU is available, 1 otherwise. # cpu_is_valid() { CPU=${1#cpu} echo "CPU is $CPU" cat /sys/devices/system/cpu/cpu${CPU}/online > /dev/null 2>&1 return $? } # cpu_is_online(CPU) # # Returns a 0 value if the given CPU number is currently online, # 1 otherwise. This function requires the system's CPUs have # hotplug capabilities. # cpu_is_online() { CPU=${1#cpu} if [ `cat /sys/devices/system/cpu/cpu${CPU}/online` = "1" ]; then return 0 else return 1 fi }