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