cpu-on-off-test.sh 5.6 KB

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