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 <[email protected]> # 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 41 42# set lowerlimit according to pagesize 43# pagesize(bytes) | lowerlimit(kb) 44# ------------------------------------ 45# 4096 | 2048 46# 16384 | 8192 47 48PAGE_SIZE=`tst_getconf PAGESIZE` 49lowerlimit=$((PAGE_SIZE * 512 / 1024)) 50 51cpus_all="$(seq -s, 0 $((nr_cpus-1)))" 52mems_all="$(seq -s, 0 $((nr_mems-1)))" 53 54nodedir="/sys/devices/system/node" 55 56FIFO="./myfifo" 57 58# memsinfo is an array implementation of the form of a multi-line string 59# _0: value0 60# _1: value1 61# _2: value2 62# 63memsinfo="" 64 65# set value to memsinfo ($1 - index, $2 - value) 66set_memsinfo_val() 67{ 68 local nl=' 69' 70 # clearing existent value (if present) 71 memsinfo=`echo "$memsinfo" | sed -r "/^\_$1\: /d"` 72 73 if [ -z "$memsinfo" ]; then 74 memsinfo="_$1: $2" 75 else 76 memsinfo="$memsinfo${nl}_$1: $2" 77 fi 78} 79 80# get value from memsinfo ($1 - index) 81get_memsinfo_val() 82{ 83 local value= 84 value=`echo "$memsinfo" | grep -e "^\_$1\: "` 85 value=`echo "$value" | sed -r "s/^.*\: (.*)$/\1/"` 86 echo "$value" 87} 88 89 90init_memsinfo_array() 91{ 92 local i= 93 94 for i in `seq 0 $((nr_mems-1))` 95 do 96 set_memsinfo_val $i 0 97 done 98} 99 100# get_meminfo <nodeid> <item> 101get_meminfo() 102{ 103 local nodeid="$1" 104 local nodepath="$nodedir/node$nodeid" 105 local nodememinfo="$nodepath/meminfo" 106 local item="$2" 107 local info=`cat $nodememinfo | grep $item | awk '{print $4}'` 108 set_memsinfo_val $nodeid $info 109} 110 111# freemem_check 112# We need enough memory space on every node to run this test, so we must check 113# whether every node has enough free memory or not. 114# return value: 1 - Some node doesn't have enough free memory 115# 0 - Every node has enough free memory, We can do this test 116freemem_check() 117{ 118 local i= 119 120 for i in `seq 0 $((nr_mems-1))` 121 do 122 get_meminfo $i "MemFree" 123 done 124 125 for i in `seq 0 $((nr_mems-1))` 126 do 127 # I think we need 100MB free memory to run test 128 if [ $(get_memsinfo_val $i) -lt 100000 ]; then 129 return 1 130 fi 131 done 132} 133 134# get_memsinfo 135get_memsinfo() 136{ 137 local i= 138 139 for i in `seq 0 $((nr_mems-1))` 140 do 141 get_meminfo $i "FilePages" 142 done 143} 144 145# account_meminfo <nodeId> 146account_meminfo() 147{ 148 local nodeId="$1" 149 local tmp="$(get_memsinfo_val $nodeId)" 150 get_meminfo $@ "FilePages" 151 set_memsinfo_val $nodeId $(($(get_memsinfo_val $nodeId)-$tmp)) 152} 153 154# account_memsinfo 155account_memsinfo() 156{ 157 local i= 158 159 for i in `seq 0 $((nr_mems-1))` 160 do 161 account_meminfo $i 162 done 163} 164 165 166# result_check <nodelist> 167# return 0: success 168# 1: fail 169result_check() 170{ 171 local nodelist="`echo $1 | sed -e 's/,/ /g'`" 172 local i= 173 174 for i in $nodelist 175 do 176 if [ $(get_memsinfo_val $i) -le $upperlimit ]; then 177 return 1 178 fi 179 done 180 181 local allnodelist="`echo $mems_all | sed -e 's/,/ /g'`" 182 allnodelist=" "$allnodelist" " 183 nodelist=" "$nodelist" " 184 185 local othernodelist="$allnodelist" 186 for i in $nodelist 187 do 188 othernodelist=`echo "$othernodelist" | sed -e "s/ $i / /g"` 189 done 190 191 for i in $othernodelist 192 do 193 if [ $(get_memsinfo_val $i) -gt $lowerlimit ]; then 194 return 1 195 fi 196 done 197} 198 199# general_memory_spread_test <cpusetpath> <is_spread> <cpu_list> <node_list> \ 200# <expect_nodes> <test_pid> 201# expect_nodes: we expect to use the slab or cache on which node 202general_memory_spread_test() 203{ 204 local cpusetpath="$CPUSET/1" 205 local is_spread="$1" 206 local cpu_list="$2" 207 local node_list="$3" 208 local expect_nodes="$4" 209 local test_pid="$5" 210 211 cpuset_set "$cpusetpath" "$cpu_list" "$node_list" "0" 2> $CPUSET_TMP/stderr 212 if [ $? -ne 0 ]; then 213 cpuset_log_error $CPUSET_TMP/stderr 214 tst_resm TFAIL "set general group parameter failed." 215 return 1 216 fi 217 218 /bin/echo "$is_spread" > "$cpusetpath/cpuset.memory_spread_page" 2> $CPUSET_TMP/stderr 219 if [ $? -ne 0 ]; then 220 cpuset_log_error $CPUSET_TMP/stderr 221 tst_resm TFAIL "set spread value failed." 222 return 1 223 fi 224 225 /bin/echo "$test_pid" > "$cpusetpath/tasks" 2> $CPUSET_TMP/stderr 226 if [ $? -ne 0 ]; then 227 cpuset_log_error $CPUSET_TMP/stderr 228 tst_resm TFAIL "attach task failed." 229 return 1 230 fi 231 232 # we'd better drop the caches before we test page cache. 233 sync 234 /bin/echo 3 > /proc/sys/vm/drop_caches 2> $CPUSET_TMP/stderr 235 if [ $? -ne 0 ]; then 236 cpuset_log_error $CPUSET_TMP/stderr 237 tst_resm TFAIL "drop caches failed." 238 return 1 239 fi 240 241 get_memsinfo 242 /bin/kill -s SIGUSR1 $test_pid 243 read exit_num < $FIFO 244 if [ $exit_num -eq 0 ]; then 245 tst_resm TFAIL "hot mem task failed." 246 return 1 247 fi 248 249 account_memsinfo 250 result_check $expect_nodes 251 if [ $? -ne 0 ]; then 252 tst_resm TFAIL "hog the memory on the unexpected node(FilePages_For_Nodes(KB): ${memsinfo}, Expect Nodes: $expect_nodes)." 253 return 1 254 fi 255} 256 257base_test() 258{ 259 local pid= 260 local result_num= 261 262 setup 263 if [ $? -ne 0 ]; then 264 exit_status=1 265 else 266 cpuset_mem_hog & 267 pid=$! 268 general_memory_spread_test "$@" "$pid" 269 result_num=$? 270 if [ $result_num -ne 0 ]; then 271 exit_status=1 272 fi 273 274 /bin/kill -s SIGUSR2 $pid 275 wait $pid 276 277 cleanup 278 if [ $? -ne 0 ]; then 279 exit_status=1 280 elif [ $result_num -eq 0 ]; then 281 tst_resm TPASS "Cpuset memory spread page test succeeded." 282 fi 283 fi 284 TST_COUNT=$(($TST_COUNT + 1)) 285} 286 287# test general spread page cache in a cpuset 288test_spread_page1() 289{ 290 while read spread cpus nodes exp_nodes 291 do 292 base_test "$spread" "$cpus" "$nodes" "$exp_nodes" 293 done <<- EOF 294 0 0 0 0 295 1 0 0 0 296 0 0 1 1 297 1 0 1 1 298 0 0 0,1 0 299 1 0 0,1 0,1 300 EOF 301 # while read spread cpus nodes exp_nodes 302} 303 304test_spread_page2() 305{ 306 local pid= 307 local result_num= 308 309 setup 310 if [ $? -ne 0 ]; then 311 exit_status=1 312 else 313 cpuset_mem_hog & 314 pid=$! 315 general_memory_spread_test "1" "$cpus_all" "0" "0" "$pid" 316 result_num=$? 317 if [ $result_num -ne 0 ]; then 318 exit_status=1 319 else 320 general_memory_spread_test "1" "$cpus_all" "1" "1" "$pid" 321 result_num=$? 322 if [ $result_num -ne 0 ]; then 323 exit_status=1 324 fi 325 fi 326 327 /bin/kill -s SIGUSR2 $pid 328 wait $pid 329 330 cleanup 331 if [ $? -ne 0 ]; then 332 exit_status=1 333 elif [ $result_num -eq 0 ]; then 334 tst_resm TPASS "Cpuset memory spread page test succeeded." 335 fi 336 fi 337} 338 339init_memsinfo_array 340freemem_check 341if [ $? -ne 0 ]; then 342 tst_brkm TCONF "Some node doesn't has enough free memory(100MB) to do test(MemFree_For_Nodes(KB): ${memsinfo[*]})." 343fi 344 345dd if=/dev/zero of=./DATAFILE bs=1M count=100 346if [ $? -ne 0 ]; then 347 tst_brkm TFAIL "Creating DATAFILE failed." 348fi 349 350mkfifo $FIFO 351if [ $? -ne 0 ]; then 352 rm -f DATAFILE 353 tst_brkm TFAIL "failed to mkfifo $FIFO" 354fi 355 356test_spread_page1 357test_spread_page2 358 359rm -f DATAFILE $FIFO 360 361exit $exit_status 362