cpuset_memory_spread_testset.sh 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. #!/bin/sh
  2. ################################################################################
  3. # #
  4. # Copyright (c) 2009 FUJITSU LIMITED #
  5. # #
  6. # This program is free software; you can redistribute it and#or modify #
  7. # it under the terms of the GNU General Public License as published by #
  8. # the Free Software Foundation; either version 2 of the License, or #
  9. # (at your option) any later version. #
  10. # #
  11. # This program is distributed in the hope that it will be useful, but #
  12. # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
  13. # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License #
  14. # for more details. #
  15. # #
  16. # You should have received a copy of the GNU General Public License #
  17. # along with this program; if not, write to the Free Software #
  18. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #
  19. # #
  20. # Author: Miao Xie <miaox@cn.fujitsu.com> #
  21. # #
  22. ################################################################################
  23. export TCID="cpuset_memory_spread"
  24. export TST_TOTAL=6
  25. export TST_COUNT=1
  26. . cpuset_funcs.sh
  27. check
  28. exit_status=0
  29. nr_cpus=$NR_CPUS
  30. nr_mems=$N_NODES
  31. # In general, the cache hog will use more than 10000 kb slab space on the nodes
  32. # on which it is running. The other nodes' slab space has littler change.(less
  33. # than 1000 kb).
  34. upperlimit=10000
  35. lowerlimit=2000
  36. cpus_all="$(seq -s, 0 $((nr_cpus-1)))"
  37. mems_all="$(seq -s, 0 $((nr_mems-1)))"
  38. nodedir="/sys/devices/system/node"
  39. FIFO="./myfifo"
  40. # memsinfo is an array implementation of the form of a multi-line string
  41. # _0: value0
  42. # _1: value1
  43. # _2: value2
  44. #
  45. memsinfo=""
  46. # set value to memsinfo ($1 - index, $2 - value)
  47. set_memsinfo_val()
  48. {
  49. local nl='
  50. '
  51. # clearing existent value (if present)
  52. memsinfo=`echo "$memsinfo" | sed -r "/^\_$1\: /d"`
  53. if [ -z "$memsinfo" ]; then
  54. memsinfo="_$1: $2"
  55. else
  56. memsinfo="$memsinfo${nl}_$1: $2"
  57. fi
  58. }
  59. # get value from memsinfo ($1 - index)
  60. get_memsinfo_val()
  61. {
  62. local value=
  63. value=`echo "$memsinfo" | grep -e "^\_$1\: "`
  64. value=`echo "$value" | sed -r "s/^.*\: (.*)$/\1/"`
  65. echo "$value"
  66. }
  67. init_memsinfo_array()
  68. {
  69. local i=
  70. for i in `seq 0 $((nr_mems-1))`
  71. do
  72. set_memsinfo_val $i 0
  73. done
  74. }
  75. # get_meminfo <nodeid> <item>
  76. get_meminfo()
  77. {
  78. local nodeid="$1"
  79. local nodepath="$nodedir/node$nodeid"
  80. local nodememinfo="$nodepath/meminfo"
  81. local item="$2"
  82. local info=`cat $nodememinfo | grep $item | awk '{print $4}'`
  83. set_memsinfo_val $nodeid $info
  84. }
  85. # freemem_check
  86. # We need enough memory space on every node to run this test, so we must check
  87. # whether every node has enough free memory or not.
  88. # return value: 1 - Some node doesn't have enough free memory
  89. # 0 - Every node has enough free memory, We can do this test
  90. freemem_check()
  91. {
  92. local i=
  93. for i in `seq 0 $((nr_mems-1))`
  94. do
  95. get_meminfo $i "MemFree"
  96. done
  97. for i in `seq 0 $((nr_mems-1))`
  98. do
  99. # I think we need 100MB free memory to run test
  100. if [ $(get_memsinfo_val $i) -lt 100000 ]; then
  101. return 1
  102. fi
  103. done
  104. }
  105. # get_memsinfo
  106. get_memsinfo()
  107. {
  108. local i=
  109. for i in `seq 0 $((nr_mems-1))`
  110. do
  111. get_meminfo $i "FilePages"
  112. done
  113. }
  114. # account_meminfo <nodeId>
  115. account_meminfo()
  116. {
  117. local nodeId="$1"
  118. local tmp="$(get_memsinfo_val $nodeId)"
  119. get_meminfo $@ "FilePages"
  120. set_memsinfo_val $nodeId $(($(get_memsinfo_val $nodeId)-$tmp))
  121. }
  122. # account_memsinfo
  123. account_memsinfo()
  124. {
  125. local i=
  126. for i in `seq 0 $((nr_mems-1))`
  127. do
  128. account_meminfo $i
  129. done
  130. }
  131. # result_check <nodelist>
  132. # return 0: success
  133. # 1: fail
  134. result_check()
  135. {
  136. local nodelist="`echo $1 | sed -e 's/,/ /g'`"
  137. local i=
  138. for i in $nodelist
  139. do
  140. if [ $(get_memsinfo_val $i) -le $upperlimit ]; then
  141. return 1
  142. fi
  143. done
  144. local allnodelist="`echo $mems_all | sed -e 's/,/ /g'`"
  145. allnodelist=" "$allnodelist" "
  146. nodelist=" "$nodelist" "
  147. local othernodelist="$allnodelist"
  148. for i in $nodelist
  149. do
  150. othernodelist=`echo "$othernodelist" | sed -e "s/ $i / /g"`
  151. done
  152. for i in $othernodelist
  153. do
  154. if [ $(get_memsinfo_val $i) -gt $lowerlimit ]; then
  155. return 1
  156. fi
  157. done
  158. }
  159. # general_memory_spread_test <cpusetpath> <is_spread> <cpu_list> <node_list> \
  160. # <expect_nodes> <test_pid>
  161. # expect_nodes: we expect to use the slab or cache on which node
  162. general_memory_spread_test()
  163. {
  164. local cpusetpath="$CPUSET/1"
  165. local is_spread="$1"
  166. local cpu_list="$2"
  167. local node_list="$3"
  168. local expect_nodes="$4"
  169. local test_pid="$5"
  170. cpuset_set "$cpusetpath" "$cpu_list" "$node_list" "0" 2> $CPUSET_TMP/stderr
  171. if [ $? -ne 0 ]; then
  172. cpuset_log_error $CPUSET_TMP/stderr
  173. tst_resm TFAIL "set general group parameter failed."
  174. return 1
  175. fi
  176. /bin/echo "$is_spread" > "$cpusetpath/cpuset.memory_spread_page" 2> $CPUSET_TMP/stderr
  177. if [ $? -ne 0 ]; then
  178. cpuset_log_error $CPUSET_TMP/stderr
  179. tst_resm TFAIL "set spread value failed."
  180. return 1
  181. fi
  182. /bin/echo "$test_pid" > "$cpusetpath/tasks" 2> $CPUSET_TMP/stderr
  183. if [ $? -ne 0 ]; then
  184. cpuset_log_error $CPUSET_TMP/stderr
  185. tst_resm TFAIL "attach task failed."
  186. return 1
  187. fi
  188. # we'd better drop the caches before we test page cache.
  189. sync
  190. /bin/echo 3 > /proc/sys/vm/drop_caches 2> $CPUSET_TMP/stderr
  191. if [ $? -ne 0 ]; then
  192. cpuset_log_error $CPUSET_TMP/stderr
  193. tst_resm TFAIL "drop caches failed."
  194. return 1
  195. fi
  196. get_memsinfo
  197. /bin/kill -s SIGUSR1 $test_pid
  198. read exit_num < $FIFO
  199. if [ $exit_num -eq 0 ]; then
  200. tst_resm TFAIL "hot mem task failed."
  201. return 1
  202. fi
  203. account_memsinfo
  204. result_check $expect_nodes
  205. if [ $? -ne 0 ]; then
  206. tst_resm TFAIL "hog the memory on the unexpected node(FilePages_For_Nodes(KB): ${memsinfo}, Expect Nodes: $expect_nodes)."
  207. return 1
  208. fi
  209. }
  210. base_test()
  211. {
  212. local pid=
  213. local result_num=
  214. setup
  215. if [ $? -ne 0 ]; then
  216. exit_status=1
  217. else
  218. cpuset_mem_hog &
  219. pid=$!
  220. general_memory_spread_test "$@" "$pid"
  221. result_num=$?
  222. if [ $result_num -ne 0 ]; then
  223. exit_status=1
  224. fi
  225. /bin/kill -s SIGUSR2 $pid
  226. wait $pid
  227. cleanup
  228. if [ $? -ne 0 ]; then
  229. exit_status=1
  230. elif [ $result_num -eq 0 ]; then
  231. tst_resm TPASS "Cpuset memory spread page test succeeded."
  232. fi
  233. fi
  234. TST_COUNT=$(($TST_COUNT + 1))
  235. }
  236. # test general spread page cache in a cpuset
  237. test_spread_page1()
  238. {
  239. while read spread cpus nodes exp_nodes
  240. do
  241. base_test "$spread" "$cpus" "$nodes" "$exp_nodes"
  242. done <<- EOF
  243. 0 0 0 0
  244. 1 0 0 0
  245. 0 0 1 1
  246. 1 0 1 1
  247. 0 0 0,1 0
  248. 1 0 0,1 0,1
  249. EOF
  250. # while read spread cpus nodes exp_nodes
  251. }
  252. test_spread_page2()
  253. {
  254. local pid=
  255. local result_num=
  256. setup
  257. if [ $? -ne 0 ]; then
  258. exit_status=1
  259. else
  260. cpuset_mem_hog &
  261. pid=$!
  262. general_memory_spread_test "1" "$cpus_all" "0" "0" "$pid"
  263. result_num=$?
  264. if [ $result_num -ne 0 ]; then
  265. exit_status=1
  266. else
  267. general_memory_spread_test "1" "$cpus_all" "1" "1" "$pid"
  268. result_num=$?
  269. if [ $result_num -ne 0 ]; then
  270. exit_status=1
  271. fi
  272. fi
  273. /bin/kill -s SIGUSR2 $pid
  274. wait $pid
  275. cleanup
  276. if [ $? -ne 0 ]; then
  277. exit_status=1
  278. elif [ $result_num -eq 0 ]; then
  279. tst_resm TPASS "Cpuset memory spread page test succeeded."
  280. fi
  281. fi
  282. }
  283. init_memsinfo_array
  284. freemem_check
  285. if [ $? -ne 0 ]; then
  286. tst_brkm TCONF "Some node doesn't has enough free memory(100MB) to do test(MemFree_For_Nodes(KB): ${memsinfo[*]})."
  287. fi
  288. dd if=/dev/zero of=./DATAFILE bs=1M count=100
  289. if [ $? -ne 0 ]; then
  290. tst_brkm TFAIL "Creating DATAFILE failed."
  291. fi
  292. mkfifo $FIFO
  293. if [ $? -ne 0 ]; then
  294. rm -f DATAFILE
  295. tst_brkm TFAIL "failed to mkfifo $FIFO"
  296. fi
  297. test_spread_page1
  298. test_spread_page2
  299. rm -f DATAFILE $FIFO
  300. exit $exit_status