memcg_lib.sh revision 4548c6cf9bcdd96d8303caa4130ab638b61f8a30
1#! /bin/sh 2 3################################################################################ 4## ## 5## Copyright (c) 2012 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: Peng Haitao <penght@cn.fujitsu.com> ## 22## ## 23################################################################################ 24 25if [ "x$(grep -w memory /proc/cgroups | cut -f4)" != "x1" ]; then 26 echo "WARNING:"; 27 echo "Either Kernel does not support for memory resource controller or feature not enabled"; 28 echo "Skipping all memcgroup testcases...."; 29 exit 0 30fi 31 32cd $LTPROOT/testcases/bin 33 34TEST_PATH=$PWD 35PAGESIZE=`./memcg_getpagesize` 36HUGEPAGESIZE=`grep Hugepagesize /proc/meminfo | awk '{ print $2 }'` 37[ -z $HUGEPAGESIZE ] && HUGEPAGESIZE=0 38HUGEPAGESIZE=$(( $HUGEPAGESIZE * 1024 )) 39PASS=0 40FAIL=1 41 42cur_id=0 43failed=0 44 45# Record the test result of a test case 46# $1 - The result of the test case, $PASS or $FAIL 47# $2 - The output information 48result() 49{ 50 local pass=$1 51 local info="$2" 52 53 if [ $pass -eq $PASS ]; then 54 tst_resm TPASS "$info" 55 else 56 tst_resm TFAIL "$info" 57 : $(( failed += 1 )) 58 fi 59} 60 61# Check size in memcg 62# $1 - Item name 63# $2 - Expected size 64check_mem_stat() 65{ 66 if [ -e $1 ]; then 67 item_size=`cat $1` 68 else 69 item_size=`grep -w $1 memory.stat | cut -d " " -f 2` 70 fi 71 72 if [ "$2" = "$item_size" ]; then 73 pass=$PASS 74 else 75 pass=$FAIL 76 fi 77 78 result $pass "$1=$item_size/$2" 79} 80 81warmup() 82{ 83 pid=$1 84 85 echo "Warming up for test: $cur_id, pid: $pid" 86 kill -s USR1 $pid 2> /dev/null 87 sleep 1 88 kill -s USR1 $pid 2> /dev/null 89 sleep 1 90 91 kill -0 $pid 92 if [ $? -ne 0 ]; then 93 result $FAIL "cur_id=$cur_id" 94 return 1 95 else 96 echo "Process is still here after warm up: $pid" 97 fi 98 99 return 0 100} 101 102# Run test cases which checks memory.stat after make 103# some memory allocation 104# $1 - the parameters of 'process', such as --shm 105# $2 - the -s parameter of 'process', such as 4096 106# $3 - item name in memory.stat 107# $4 - the expected size 108# $5 - check after free ? 109test_mem_stat() 110{ 111 echo "Running $TEST_PATH/memcg_process $1 -s $2" 112 $TEST_PATH/memcg_process $1 -s $2 & 113 sleep 1 114 115 warmup $! 116 if [ $? -ne 0 ]; then 117 return 118 fi 119 120 echo $! > tasks 121 kill -s USR1 $! 2> /dev/null 122 sleep 1 123 124 check_mem_stat $3 $4 125 126 kill -s USR1 $! 2> /dev/null 127 sleep 1 128 if [ $5 -eq 1 ]; then 129 check_mem_stat $3 0 130 fi 131 132 kill -s INT $! 2> /dev/null 133} 134 135# Run test cases which checks memory.max_usage_in_bytes after make 136# some memory allocation 137# $1 - the parameters of 'process', such as --shm 138# $2 - the -s parameter of 'process', such as 4096 139# $3 - item name 140# $4 - the expected size 141# $5 - check after free ? 142test_max_usage_in_bytes() 143{ 144 echo "Running $TEST_PATH/memcg_process $1 -s $2" 145 $TEST_PATH/memcg_process $1 -s $2 & 146 sleep 1 147 148 warmup $! 149 if [ $? -ne 0 ]; then 150 return 151 fi 152 153 echo $! > tasks 154 kill -s USR1 $! 2> /dev/null 155 sleep 1 156 157 kill -s USR1 $! 2> /dev/null 158 sleep 1 159 160 check_mem_stat $3 $4 161 162 if [ $5 -eq 1 ]; then 163 echo 0 > $3 164 check_mem_stat $3 0 165 fi 166 167 kill -s INT $! 2> /dev/null 168} 169 170# make some memory allocation 171# $1 - the parameters of 'process', such as --shm 172# $2 - the -s parameter of 'process', such as 4096 173malloc_free_memory() 174{ 175 echo "Running $TEST_PATH/memcg_process $1 -s $2" 176 $TEST_PATH/memcg_process $1 -s $2 & 177 sleep 1 178 179 echo $! > tasks 180 kill -s USR1 $! 2> /dev/null 181 sleep 1 182 183 kill -s USR1 $! 2> /dev/null 184 sleep 1 185 186 kill -s INT $! 2> /dev/null 187} 188 189# Test if failcnt > 0, which means page reclamation occured 190# $1 - item name in memcg 191test_failcnt() 192{ 193 failcnt=`cat $1` 194 if [ $failcnt -gt 0 ]; then 195 pass=$PASS 196 else 197 pass=$FAIL 198 fi 199 200 result $pass "$1=$failcnt" 201} 202 203# Test process will be killed due to exceed memory limit 204# $1 - the value of memory.limit_in_bytes 205# $2 - the parameters of 'process', such as --shm 206# $3 - the -s parameter of 'process', such as 4096 207# $4 - use mem+swap limitation 208test_proc_kill() 209{ 210 echo $1 > memory.limit_in_bytes 211 if [ $4 -eq 1 ]; then 212 if [ -e memory.memsw.limit_in_bytes ]; then 213 echo $1 > memory.memsw.limit_in_bytes 214 else 215 tst_resm TCONF "mem+swap is not enabled" 216 return 217 fi 218 fi 219 220 $TEST_PATH/memcg_process $2 -s $3 & 221 pid=$! 222 sleep 1 223 echo $pid > tasks 224 225 kill -s USR1 $pid 2> /dev/null 226 sleep 1 227 228 ps -p $pid > /dev/null 2> /dev/null 229 if [ $? -ne 0 ]; then 230 wait $pid 231 if [ $? -eq 1 ]; then 232 result $FAIL "process $pid is killed by error" 233 else 234 result $PASS "process $pid is killed" 235 fi 236 else 237 kill -s INT $pid 2> /dev/null 238 result $FAIL "process $pid is not killed" 239 fi 240} 241 242# Test limit_in_bytes will be aligned to PAGESIZE 243# $1 - user input value 244# $2 - expected value 245# $3 - use mem+swap limitation 246test_limit_in_bytes() 247{ 248 echo $1 > memory.limit_in_bytes 249 if [ $3 -eq 1 ]; then 250 if [ -e memory.memsw.limit_in_bytes ]; then 251 echo $1 > memory.memsw.limit_in_bytes 252 limit=`cat memory.memsw.limit_in_bytes` 253 else 254 tst_resm TCONF "mem+swap is not enabled" 255 return 256 fi 257 else 258 limit=`cat memory.limit_in_bytes` 259 fi 260 261 if [ $limit -eq $2 ]; then 262 result $PASS "input=$1, limit_in_bytes=$limit" 263 else 264 result $FAIL "input=$1, limit_in_bytes=$limit" 265 fi 266} 267 268# Test memory controller doesn't charge hugepage 269# $1 - the value of /proc/sys/vm/nr_hugepages 270# $2 - the parameters of 'process', --mmap-file or --shm 271# $3 - the -s parameter of 'process', such as $HUGEPAGESIZE 272# $4 - 0: expected failure, 1: expected success 273test_hugepage() 274{ 275 TMP_FILE=$TEST_PATH/tmp 276 nr_hugepages=`cat /proc/sys/vm/nr_hugepages` 277 278 mkdir /hugetlb 279 mount -t hugetlbfs none /hugetlb 280 281 echo $1 > /proc/sys/vm/nr_hugepages 282 283 $TEST_PATH/memcg_process $2 --hugepage -s $3 > $TMP_FILE 2>&1 & 284 sleep 1 285 286 kill -s USR1 $! 2> /dev/null 287 sleep 1 288 289 check_mem_stat "rss" 0 290 291 echo "TMP_FILE:" 292 cat $TMP_FILE 293 294 if [ $4 -eq 0 ]; then 295 test -s $TMP_FILE 296 if [ $? -eq 0 ]; then 297 result $PASS "allocate hugepage failed as expected" 298 else 299 kill -s USR1 $! 2> /dev/null 300 kill -s INT $! 2> /dev/null 301 result $FAIL "allocate hugepage shoud fail" 302 fi 303 else 304 test ! -s $TMP_FILE 305 if [ $? -eq 0 ]; then 306 kill -s USR1 $! 2> /dev/null 307 kill -s INT $! 2> /dev/null 308 result $PASS "allocate hugepage succeeded" 309 else 310 result $FAIL "allocate hugepage failed" 311 fi 312 fi 313 314 sleep 1 315 rm -rf $TMP_FILE 316 umount /hugetlb 317 rmdir /hugetlb 318 echo $nr_hugepages > /proc/sys/vm/nr_hugepages 319} 320 321# Test the memory charge won't move to subgroup 322# $1 - memory.limit_in_bytes in parent group 323# $2 - memory.limit_in_bytes in sub group 324test_subgroup() 325{ 326 mkdir subgroup 327 echo $1 > memory.limit_in_bytes 328 echo $2 > subgroup/memory.limit_in_bytes 329 330 echo "Running $TEST_PATH/memcg_process --mmap-anon -s $PAGESIZE" 331 $TEST_PATH/memcg_process --mmap-anon -s $PAGESIZE & 332 sleep 1 333 334 warmup $! 335 if [ $? -ne 0 ]; then 336 return 337 fi 338 339 echo $! > tasks 340 kill -s USR1 $! 2> /dev/null 341 sleep 1 342 check_mem_stat "rss" $PAGESIZE 343 344 cd subgroup 345 echo $! > tasks 346 check_mem_stat "rss" 0 347 348 # cleanup 349 cd .. 350 echo $! > tasks 351 kill -s INT $! 2> /dev/null 352 sleep 1 353 rmdir subgroup 354} 355 356# Run test cases which test memory.move_charge_at_immigrate 357# $1 - the parameters of 'process', such as --shm 358# $2 - the -s parameter of 'process', such as 4096 359# $3 - some positive value, such as 1 360# $4 - the expected size 361# $5 - the expected size 362test_move_charge() 363{ 364 mkdir subgroup_a 365 366 $TEST_PATH/memcg_process $1 -s $2 & 367 sleep 1 368 warmup $! 369 if [ $? -ne 0 ]; then 370 rmdir subgroup_a 371 return 372 fi 373 374 echo $! > subgroup_a/tasks 375 kill -s USR1 $! 376 sleep 1 377 378 mkdir subgroup_b 379 echo $3 > subgroup_b/memory.move_charge_at_immigrate 380 echo $! > subgroup_b/tasks 381 382 cd subgroup_b 383 check_mem_stat "rss" $4 384 check_mem_stat "cache" $5 385 cd ../subgroup_a 386 check_mem_stat "rss" $6 387 check_mem_stat "cache" $7 388 389 cd .. 390 echo $! > tasks 391 kill -s USR1 $! 392 kill -s INT $! 393 sleep 1 394 rmdir subgroup_a subgroup_b 395} 396 397cleanup() 398{ 399 killall -9 memcg_process 2>/dev/null 400 if [ -e /dev/memcg ]; then 401 umount /dev/memcg 2>/dev/null 402 rmdir /dev/memcg 2>/dev/null 403 fi 404} 405 406do_mount() 407{ 408 cleanup 409 410 mkdir /dev/memcg 2> /dev/null 411 mount -t cgroup -omemory memcg /dev/memcg 412} 413