cpu-on-off-test.sh 5.3 KB

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