cpuhotplug_hotplug.sh 6.1 KB

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