cpu-on-off-test.sh 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #!/bin/bash
  2. SYSFS=
  3. prerequisite()
  4. {
  5. msg="skip all tests:"
  6. if [ $UID != 0 ]; then
  7. echo $msg must be run as root >&2
  8. exit 0
  9. fi
  10. taskset -p 01 $$
  11. SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
  12. if [ ! -d "$SYSFS" ]; then
  13. echo $msg sysfs is not mounted >&2
  14. exit 0
  15. fi
  16. if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then
  17. echo $msg cpu hotplug is not supported >&2
  18. exit 0
  19. fi
  20. echo "CPU online/offline summary:"
  21. online_cpus=`cat $SYSFS/devices/system/cpu/online`
  22. online_max=${online_cpus##*-}
  23. echo -e "\t Cpus in online state: $online_cpus"
  24. offline_cpus=`cat $SYSFS/devices/system/cpu/offline`
  25. if [[ "a$offline_cpus" = "a" ]]; then
  26. offline_cpus=0
  27. else
  28. offline_max=${offline_cpus##*-}
  29. fi
  30. echo -e "\t Cpus in offline state: $offline_cpus"
  31. }
  32. #
  33. # list all hot-pluggable CPUs
  34. #
  35. hotpluggable_cpus()
  36. {
  37. local state=${1:-.\*}
  38. for cpu in $SYSFS/devices/system/cpu/cpu*; do
  39. if [ -f $cpu/online ] && grep -q $state $cpu/online; then
  40. echo ${cpu##/*/cpu}
  41. fi
  42. done
  43. }
  44. hotplaggable_offline_cpus()
  45. {
  46. hotpluggable_cpus 0
  47. }
  48. hotpluggable_online_cpus()
  49. {
  50. hotpluggable_cpus 1
  51. }
  52. cpu_is_online()
  53. {
  54. grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online
  55. }
  56. cpu_is_offline()
  57. {
  58. grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online
  59. }
  60. online_cpu()
  61. {
  62. echo 1 > $SYSFS/devices/system/cpu/cpu$1/online
  63. }
  64. offline_cpu()
  65. {
  66. echo 0 > $SYSFS/devices/system/cpu/cpu$1/online
  67. }
  68. online_cpu_expect_success()
  69. {
  70. local cpu=$1
  71. if ! online_cpu $cpu; then
  72. echo $FUNCNAME $cpu: unexpected fail >&2
  73. elif ! cpu_is_online $cpu; then
  74. echo $FUNCNAME $cpu: unexpected offline >&2
  75. fi
  76. }
  77. online_cpu_expect_fail()
  78. {
  79. local cpu=$1
  80. if online_cpu $cpu 2> /dev/null; then
  81. echo $FUNCNAME $cpu: unexpected success >&2
  82. elif ! cpu_is_offline $cpu; then
  83. echo $FUNCNAME $cpu: unexpected online >&2
  84. fi
  85. }
  86. offline_cpu_expect_success()
  87. {
  88. local cpu=$1
  89. if ! offline_cpu $cpu; then
  90. echo $FUNCNAME $cpu: unexpected fail >&2
  91. elif ! cpu_is_offline $cpu; then
  92. echo $FUNCNAME $cpu: unexpected offline >&2
  93. fi
  94. }
  95. offline_cpu_expect_fail()
  96. {
  97. local cpu=$1
  98. if offline_cpu $cpu 2> /dev/null; then
  99. echo $FUNCNAME $cpu: unexpected success >&2
  100. elif ! cpu_is_online $cpu; then
  101. echo $FUNCNAME $cpu: unexpected offline >&2
  102. fi
  103. }
  104. error=-12
  105. allcpus=0
  106. priority=0
  107. online_cpus=0
  108. online_max=0
  109. offline_cpus=0
  110. offline_max=0
  111. while getopts e:ahp: opt; do
  112. case $opt in
  113. e)
  114. error=$OPTARG
  115. ;;
  116. a)
  117. allcpus=1
  118. ;;
  119. h)
  120. echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]"
  121. echo -e "\t default offline one cpu"
  122. echo -e "\t run with -a option to offline all cpus"
  123. exit
  124. ;;
  125. p)
  126. priority=$OPTARG
  127. ;;
  128. esac
  129. done
  130. if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
  131. echo "error code must be -4095 <= errno < 0" >&2
  132. exit 1
  133. fi
  134. prerequisite
  135. #
  136. # Safe test (default) - offline and online one cpu
  137. #
  138. if [ $allcpus -eq 0 ]; then
  139. echo "Limited scope test: one hotplug cpu"
  140. echo -e "\t (leaves cpu in the original state):"
  141. echo -e "\t online to offline to online: cpu $online_max"
  142. offline_cpu_expect_success $online_max
  143. online_cpu_expect_success $online_max
  144. if [[ $offline_cpus -gt 0 ]]; then
  145. echo -e "\t offline to online to offline: cpu $offline_max"
  146. online_cpu_expect_success $offline_max
  147. offline_cpu_expect_success $offline_max
  148. fi
  149. exit 0
  150. else
  151. echo "Full scope test: all hotplug cpus"
  152. echo -e "\t online all offline cpus"
  153. echo -e "\t offline all online cpus"
  154. echo -e "\t online all offline cpus"
  155. fi
  156. #
  157. # Online all hot-pluggable CPUs
  158. #
  159. for cpu in `hotplaggable_offline_cpus`; do
  160. online_cpu_expect_success $cpu
  161. done
  162. #
  163. # Offline all hot-pluggable CPUs
  164. #
  165. for cpu in `hotpluggable_online_cpus`; do
  166. offline_cpu_expect_success $cpu
  167. done
  168. #
  169. # Online all hot-pluggable CPUs again
  170. #
  171. for cpu in `hotplaggable_offline_cpus`; do
  172. online_cpu_expect_success $cpu
  173. done
  174. #
  175. # Test with cpu notifier error injection
  176. #
  177. DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
  178. NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu
  179. prerequisite_extra()
  180. {
  181. msg="skip extra tests:"
  182. /sbin/modprobe -q -r cpu-notifier-error-inject
  183. /sbin/modprobe -q cpu-notifier-error-inject priority=$priority
  184. if [ ! -d "$DEBUGFS" ]; then
  185. echo $msg debugfs is not mounted >&2
  186. exit 0
  187. fi
  188. if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
  189. echo $msg cpu-notifier-error-inject module is not available >&2
  190. exit 0
  191. fi
  192. }
  193. prerequisite_extra
  194. #
  195. # Offline all hot-pluggable CPUs
  196. #
  197. echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
  198. for cpu in `hotpluggable_online_cpus`; do
  199. offline_cpu_expect_success $cpu
  200. done
  201. #
  202. # Test CPU hot-add error handling (offline => online)
  203. #
  204. echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
  205. for cpu in `hotplaggable_offline_cpus`; do
  206. online_cpu_expect_fail $cpu
  207. done
  208. #
  209. # Online all hot-pluggable CPUs
  210. #
  211. echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
  212. for cpu in `hotplaggable_offline_cpus`; do
  213. online_cpu_expect_success $cpu
  214. done
  215. #
  216. # Test CPU hot-remove error handling (online => offline)
  217. #
  218. echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
  219. for cpu in `hotpluggable_online_cpus`; do
  220. offline_cpu_expect_fail $cpu
  221. done
  222. echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
  223. /sbin/modprobe -q -r cpu-notifier-error-inject