Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 602 lines 18 kB view raw
1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# Kselftest framework requirement - SKIP code is 4. 5ksft_skip=4 6 7set -e 8 9if [[ $(id -u) -ne 0 ]]; then 10 echo "This test must be run as root. Skipping..." 11 exit $ksft_skip 12fi 13 14if ! command -v killall >/dev/null 2>&1; then 15 echo "killall not available. Skipping..." 16 exit $ksft_skip 17fi 18 19nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages) 20 21fault_limit_file=limit_in_bytes 22reservation_limit_file=rsvd.limit_in_bytes 23fault_usage_file=usage_in_bytes 24reservation_usage_file=rsvd.usage_in_bytes 25 26if [[ "$1" == "-cgroup-v2" ]]; then 27 cgroup2=1 28 fault_limit_file=max 29 reservation_limit_file=rsvd.max 30 fault_usage_file=current 31 reservation_usage_file=rsvd.current 32fi 33 34if [[ $cgroup2 ]]; then 35 cgroup_path=$(mount -t cgroup2 | head -1 | awk '{print $3}') 36 if [[ -z "$cgroup_path" ]]; then 37 cgroup_path=$(mktemp -d) 38 mount -t cgroup2 none $cgroup_path 39 do_umount=1 40 fi 41 echo "+hugetlb" >$cgroup_path/cgroup.subtree_control 42else 43 cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') 44 if [[ -z "$cgroup_path" ]]; then 45 cgroup_path=$(mktemp -d) 46 mount -t cgroup memory,hugetlb $cgroup_path 47 do_umount=1 48 fi 49fi 50export cgroup_path 51 52function cleanup() { 53 if [[ $cgroup2 ]]; then 54 echo $$ >$cgroup_path/cgroup.procs 55 else 56 echo $$ >$cgroup_path/tasks 57 fi 58 59 if [[ -e /mnt/huge ]]; then 60 rm -rf /mnt/huge/* 61 umount /mnt/huge || echo error 62 rmdir /mnt/huge 63 fi 64 if [[ -e $cgroup_path/hugetlb_cgroup_test ]]; then 65 rmdir $cgroup_path/hugetlb_cgroup_test 66 fi 67 if [[ -e $cgroup_path/hugetlb_cgroup_test1 ]]; then 68 rmdir $cgroup_path/hugetlb_cgroup_test1 69 fi 70 if [[ -e $cgroup_path/hugetlb_cgroup_test2 ]]; then 71 rmdir $cgroup_path/hugetlb_cgroup_test2 72 fi 73 echo 0 >/proc/sys/vm/nr_hugepages 74 echo CLEANUP DONE 75} 76 77function expect_equal() { 78 local expected="$1" 79 local actual="$2" 80 local error="$3" 81 82 if [[ "$expected" != "$actual" ]]; then 83 echo "expected ($expected) != actual ($actual): $3" 84 cleanup 85 exit 1 86 fi 87} 88 89function get_machine_hugepage_size() { 90 hpz=$(grep -i hugepagesize /proc/meminfo) 91 kb=${hpz:14:-3} 92 mb=$(($kb / 1024)) 93 echo $mb 94} 95 96MB=$(get_machine_hugepage_size) 97 98function setup_cgroup() { 99 local name="$1" 100 local cgroup_limit="$2" 101 local reservation_limit="$3" 102 103 mkdir $cgroup_path/$name 104 105 echo writing cgroup limit: "$cgroup_limit" 106 echo "$cgroup_limit" >$cgroup_path/$name/hugetlb.${MB}MB.$fault_limit_file 107 108 echo writing reservation limit: "$reservation_limit" 109 echo "$reservation_limit" > \ 110 $cgroup_path/$name/hugetlb.${MB}MB.$reservation_limit_file 111 112 if [ -e "$cgroup_path/$name/cpuset.cpus" ]; then 113 echo 0 >$cgroup_path/$name/cpuset.cpus 114 fi 115 if [ -e "$cgroup_path/$name/cpuset.mems" ]; then 116 echo 0 >$cgroup_path/$name/cpuset.mems 117 fi 118} 119 120function wait_for_file_value() { 121 local path="$1" 122 local expect="$2" 123 local max_tries=60 124 125 if [[ ! -r "$path" ]]; then 126 echo "ERROR: cannot read '$path', missing or permission denied" 127 return 1 128 fi 129 130 for ((i=1; i<=max_tries; i++)); do 131 local cur="$(cat "$path")" 132 if [[ "$cur" == "$expect" ]]; then 133 return 0 134 fi 135 echo "Waiting for $path to become '$expect' (current: '$cur') (try $i/$max_tries)" 136 sleep 1 137 done 138 139 echo "ERROR: timeout waiting for $path to become '$expect'" 140 return 1 141} 142 143function wait_for_hugetlb_memory_to_get_depleted() { 144 local cgroup="$1" 145 local path="$cgroup_path/$cgroup/hugetlb.${MB}MB.$reservation_usage_file" 146 147 wait_for_file_value "$path" "0" 148} 149 150function wait_for_hugetlb_memory_to_get_reserved() { 151 local cgroup="$1" 152 local size="$2" 153 local path="$cgroup_path/$cgroup/hugetlb.${MB}MB.$reservation_usage_file" 154 155 wait_for_file_value "$path" "$size" 156} 157 158function wait_for_hugetlb_memory_to_get_written() { 159 local cgroup="$1" 160 local size="$2" 161 local path="$cgroup_path/$cgroup/hugetlb.${MB}MB.$fault_usage_file" 162 163 wait_for_file_value "$path" "$size" 164} 165 166function write_hugetlbfs_and_get_usage() { 167 local cgroup="$1" 168 local size="$2" 169 local populate="$3" 170 local write="$4" 171 local path="$5" 172 local method="$6" 173 local private="$7" 174 local expect_failure="$8" 175 local reserve="$9" 176 177 # Function return values. 178 reservation_failed=0 179 oom_killed=0 180 hugetlb_difference=0 181 reserved_difference=0 182 183 local hugetlb_usage=$cgroup_path/$cgroup/hugetlb.${MB}MB.$fault_usage_file 184 local reserved_usage=$cgroup_path/$cgroup/hugetlb.${MB}MB.$reservation_usage_file 185 186 local hugetlb_before=$(cat $hugetlb_usage) 187 local reserved_before=$(cat $reserved_usage) 188 189 echo 190 echo Starting: 191 echo hugetlb_usage="$hugetlb_before" 192 echo reserved_usage="$reserved_before" 193 echo expect_failure is "$expect_failure" 194 195 output=$(mktemp) 196 set +e 197 if [[ "$method" == "1" ]] || [[ "$method" == 2 ]] || 198 [[ "$private" == "-r" ]] && [[ "$expect_failure" != 1 ]]; then 199 200 bash write_hugetlb_memory.sh "$size" "$populate" "$write" \ 201 "$cgroup" "$path" "$method" "$private" "-l" "$reserve" 2>&1 | tee $output & 202 203 local write_result=$? 204 local write_pid=$! 205 206 until grep -q -i "DONE" $output; do 207 echo waiting for DONE signal. 208 if ! ps $write_pid > /dev/null 209 then 210 echo "FAIL: The write died" 211 cleanup 212 exit 1 213 fi 214 sleep 0.5 215 done 216 217 echo ================= write_hugetlb_memory.sh output is: 218 cat $output 219 echo ================= end output. 220 221 if [[ "$populate" == "-o" ]] || [[ "$write" == "-w" ]]; then 222 wait_for_hugetlb_memory_to_get_written "$cgroup" "$size" 223 elif [[ "$reserve" != "-n" ]]; then 224 wait_for_hugetlb_memory_to_get_reserved "$cgroup" "$size" 225 else 226 # This case doesn't produce visible effects, but we still have 227 # to wait for the async process to start and execute... 228 sleep 0.5 229 fi 230 231 echo write_result is $write_result 232 else 233 bash write_hugetlb_memory.sh "$size" "$populate" "$write" \ 234 "$cgroup" "$path" "$method" "$private" "$reserve" 235 local write_result=$? 236 237 if [[ "$reserve" != "-n" ]]; then 238 wait_for_hugetlb_memory_to_get_reserved "$cgroup" "$size" 239 fi 240 fi 241 set -e 242 243 if [[ "$write_result" == 1 ]]; then 244 reservation_failed=1 245 fi 246 247 # On linus/master, the above process gets SIGBUS'd on oomkill, with 248 # return code 135. On earlier kernels, it gets actual oomkill, with return 249 # code 137, so just check for both conditions in case we're testing 250 # against an earlier kernel. 251 if [[ "$write_result" == 135 ]] || [[ "$write_result" == 137 ]]; then 252 oom_killed=1 253 fi 254 255 local hugetlb_after=$(cat $hugetlb_usage) 256 local reserved_after=$(cat $reserved_usage) 257 258 echo After write: 259 echo hugetlb_usage="$hugetlb_after" 260 echo reserved_usage="$reserved_after" 261 262 hugetlb_difference=$(($hugetlb_after - $hugetlb_before)) 263 reserved_difference=$(($reserved_after - $reserved_before)) 264} 265 266function cleanup_hugetlb_memory() { 267 set +e 268 local cgroup="$1" 269 if [[ "$(pgrep -f write_to_hugetlbfs)" != "" ]]; then 270 echo killing write_to_hugetlbfs 271 killall -2 --wait write_to_hugetlbfs 272 wait_for_hugetlb_memory_to_get_depleted $cgroup 273 fi 274 set -e 275 276 if [[ -e /mnt/huge ]]; then 277 rm -rf /mnt/huge/* 278 umount /mnt/huge 279 rmdir /mnt/huge 280 fi 281} 282 283function run_test() { 284 local size=$(($1 * ${MB} * 1024 * 1024)) 285 local populate="$2" 286 local write="$3" 287 local cgroup_limit=$(($4 * ${MB} * 1024 * 1024)) 288 local reservation_limit=$(($5 * ${MB} * 1024 * 1024)) 289 local nr_hugepages="$6" 290 local method="$7" 291 local private="$8" 292 local expect_failure="$9" 293 local reserve="${10}" 294 295 # Function return values. 296 hugetlb_difference=0 297 reserved_difference=0 298 reservation_failed=0 299 oom_killed=0 300 301 echo nr hugepages = "$nr_hugepages" 302 echo "$nr_hugepages" >/proc/sys/vm/nr_hugepages 303 304 setup_cgroup "hugetlb_cgroup_test" "$cgroup_limit" "$reservation_limit" 305 306 mkdir -p /mnt/huge 307 mount -t hugetlbfs -o pagesize=${MB}M none /mnt/huge 308 309 write_hugetlbfs_and_get_usage "hugetlb_cgroup_test" "$size" "$populate" \ 310 "$write" "/mnt/huge/test" "$method" "$private" "$expect_failure" \ 311 "$reserve" 312 313 cleanup_hugetlb_memory "hugetlb_cgroup_test" 314 315 local final_hugetlb=$(cat $cgroup_path/hugetlb_cgroup_test/hugetlb.${MB}MB.$fault_usage_file) 316 local final_reservation=$(cat $cgroup_path/hugetlb_cgroup_test/hugetlb.${MB}MB.$reservation_usage_file) 317 318 echo $hugetlb_difference 319 echo $reserved_difference 320 expect_equal "0" "$final_hugetlb" "final hugetlb is not zero" 321 expect_equal "0" "$final_reservation" "final reservation is not zero" 322} 323 324function run_multiple_cgroup_test() { 325 local size1="$1" 326 local populate1="$2" 327 local write1="$3" 328 local cgroup_limit1="$4" 329 local reservation_limit1="$5" 330 331 local size2="$6" 332 local populate2="$7" 333 local write2="$8" 334 local cgroup_limit2="$9" 335 local reservation_limit2="${10}" 336 337 local nr_hugepages="${11}" 338 local method="${12}" 339 local private="${13}" 340 local expect_failure="${14}" 341 local reserve="${15}" 342 343 # Function return values. 344 hugetlb_difference1=0 345 reserved_difference1=0 346 reservation_failed1=0 347 oom_killed1=0 348 349 hugetlb_difference2=0 350 reserved_difference2=0 351 reservation_failed2=0 352 oom_killed2=0 353 354 echo nr hugepages = "$nr_hugepages" 355 echo "$nr_hugepages" >/proc/sys/vm/nr_hugepages 356 357 setup_cgroup "hugetlb_cgroup_test1" "$cgroup_limit1" "$reservation_limit1" 358 setup_cgroup "hugetlb_cgroup_test2" "$cgroup_limit2" "$reservation_limit2" 359 360 mkdir -p /mnt/huge 361 mount -t hugetlbfs -o pagesize=${MB}M none /mnt/huge 362 363 write_hugetlbfs_and_get_usage "hugetlb_cgroup_test1" "$size1" \ 364 "$populate1" "$write1" "/mnt/huge/test1" "$method" "$private" \ 365 "$expect_failure" "$reserve" 366 367 hugetlb_difference1=$hugetlb_difference 368 reserved_difference1=$reserved_difference 369 reservation_failed1=$reservation_failed 370 oom_killed1=$oom_killed 371 372 local cgroup1_hugetlb_usage=$cgroup_path/hugetlb_cgroup_test1/hugetlb.${MB}MB.$fault_usage_file 373 local cgroup1_reservation_usage=$cgroup_path/hugetlb_cgroup_test1/hugetlb.${MB}MB.$reservation_usage_file 374 local cgroup2_hugetlb_usage=$cgroup_path/hugetlb_cgroup_test2/hugetlb.${MB}MB.$fault_usage_file 375 local cgroup2_reservation_usage=$cgroup_path/hugetlb_cgroup_test2/hugetlb.${MB}MB.$reservation_usage_file 376 377 local usage_before_second_write=$(cat $cgroup1_hugetlb_usage) 378 local reservation_usage_before_second_write=$(cat $cgroup1_reservation_usage) 379 380 write_hugetlbfs_and_get_usage "hugetlb_cgroup_test2" "$size2" \ 381 "$populate2" "$write2" "/mnt/huge/test2" "$method" "$private" \ 382 "$expect_failure" "$reserve" 383 384 hugetlb_difference2=$hugetlb_difference 385 reserved_difference2=$reserved_difference 386 reservation_failed2=$reservation_failed 387 oom_killed2=$oom_killed 388 389 expect_equal "$usage_before_second_write" \ 390 "$(cat $cgroup1_hugetlb_usage)" "Usage changed." 391 expect_equal "$reservation_usage_before_second_write" \ 392 "$(cat $cgroup1_reservation_usage)" "Reservation usage changed." 393 394 cleanup_hugetlb_memory 395 396 local final_hugetlb=$(cat $cgroup1_hugetlb_usage) 397 local final_reservation=$(cat $cgroup1_reservation_usage) 398 399 expect_equal "0" "$final_hugetlb" \ 400 "hugetlbt_cgroup_test1 final hugetlb is not zero" 401 expect_equal "0" "$final_reservation" \ 402 "hugetlbt_cgroup_test1 final reservation is not zero" 403 404 local final_hugetlb=$(cat $cgroup2_hugetlb_usage) 405 local final_reservation=$(cat $cgroup2_reservation_usage) 406 407 expect_equal "0" "$final_hugetlb" \ 408 "hugetlb_cgroup_test2 final hugetlb is not zero" 409 expect_equal "0" "$final_reservation" \ 410 "hugetlb_cgroup_test2 final reservation is not zero" 411} 412 413cleanup 414 415for populate in "" "-o"; do 416 for method in 0 1 2; do 417 for private in "" "-r"; do 418 for reserve in "" "-n"; do 419 420 # Skip mmap(MAP_HUGETLB | MAP_SHARED). Doesn't seem to be supported. 421 if [[ "$method" == 1 ]] && [[ "$private" == "" ]]; then 422 continue 423 fi 424 425 # Skip populated shmem tests. Doesn't seem to be supported. 426 if [[ "$method" == 2"" ]] && [[ "$populate" == "-o" ]]; then 427 continue 428 fi 429 430 if [[ "$method" == 2"" ]] && [[ "$reserve" == "-n" ]]; then 431 continue 432 fi 433 434 cleanup 435 echo 436 echo 437 echo 438 echo Test normal case. 439 echo private=$private, populate=$populate, method=$method, reserve=$reserve 440 run_test 5 "$populate" "" 10 10 10 "$method" "$private" "0" "$reserve" 441 442 echo Memory charged to hugtlb=$hugetlb_difference 443 echo Memory charged to reservation=$reserved_difference 444 445 if [[ "$populate" == "-o" ]]; then 446 expect_equal "$((5 * $MB * 1024 * 1024))" "$hugetlb_difference" \ 447 "Reserved memory charged to hugetlb cgroup." 448 else 449 expect_equal "0" "$hugetlb_difference" \ 450 "Reserved memory charged to hugetlb cgroup." 451 fi 452 453 if [[ "$reserve" != "-n" ]] || [[ "$populate" == "-o" ]]; then 454 expect_equal "$((5 * $MB * 1024 * 1024))" "$reserved_difference" \ 455 "Reserved memory not charged to reservation usage." 456 else 457 expect_equal "0" "$reserved_difference" \ 458 "Reserved memory not charged to reservation usage." 459 fi 460 461 echo 'PASS' 462 463 cleanup 464 echo 465 echo 466 echo 467 echo Test normal case with write. 468 echo private=$private, populate=$populate, method=$method, reserve=$reserve 469 run_test 5 "$populate" '-w' 5 5 10 "$method" "$private" "0" "$reserve" 470 471 echo Memory charged to hugtlb=$hugetlb_difference 472 echo Memory charged to reservation=$reserved_difference 473 474 expect_equal "$((5 * $MB * 1024 * 1024))" "$hugetlb_difference" \ 475 "Reserved memory charged to hugetlb cgroup." 476 477 expect_equal "$((5 * $MB * 1024 * 1024))" "$reserved_difference" \ 478 "Reserved memory not charged to reservation usage." 479 480 echo 'PASS' 481 482 cleanup 483 continue 484 echo 485 echo 486 echo 487 echo Test more than reservation case. 488 echo private=$private, populate=$populate, method=$method, reserve=$reserve 489 490 if [ "$reserve" != "-n" ]; then 491 run_test "5" "$populate" '' "10" "2" "10" "$method" "$private" "1" \ 492 "$reserve" 493 494 expect_equal "1" "$reservation_failed" "Reservation succeeded." 495 fi 496 497 echo 'PASS' 498 499 cleanup 500 501 echo 502 echo 503 echo 504 echo Test more than cgroup limit case. 505 echo private=$private, populate=$populate, method=$method, reserve=$reserve 506 507 # Not sure if shm memory can be cleaned up when the process gets sigbus'd. 508 if [[ "$method" != 2 ]]; then 509 run_test 5 "$populate" "-w" 2 10 10 "$method" "$private" "1" "$reserve" 510 511 expect_equal "1" "$oom_killed" "Not oom killed." 512 fi 513 echo 'PASS' 514 515 cleanup 516 517 echo 518 echo 519 echo 520 echo Test normal case, multiple cgroups. 521 echo private=$private, populate=$populate, method=$method, reserve=$reserve 522 run_multiple_cgroup_test "3" "$populate" "" "10" "10" "5" \ 523 "$populate" "" "10" "10" "10" \ 524 "$method" "$private" "0" "$reserve" 525 526 echo Memory charged to hugtlb1=$hugetlb_difference1 527 echo Memory charged to reservation1=$reserved_difference1 528 echo Memory charged to hugtlb2=$hugetlb_difference2 529 echo Memory charged to reservation2=$reserved_difference2 530 531 if [[ "$reserve" != "-n" ]] || [[ "$populate" == "-o" ]]; then 532 expect_equal "3" "$reserved_difference1" \ 533 "Incorrect reservations charged to cgroup 1." 534 535 expect_equal "5" "$reserved_difference2" \ 536 "Incorrect reservation charged to cgroup 2." 537 538 else 539 expect_equal "0" "$reserved_difference1" \ 540 "Incorrect reservations charged to cgroup 1." 541 542 expect_equal "0" "$reserved_difference2" \ 543 "Incorrect reservation charged to cgroup 2." 544 fi 545 546 if [[ "$populate" == "-o" ]]; then 547 expect_equal "3" "$hugetlb_difference1" \ 548 "Incorrect hugetlb charged to cgroup 1." 549 550 expect_equal "5" "$hugetlb_difference2" \ 551 "Incorrect hugetlb charged to cgroup 2." 552 553 else 554 expect_equal "0" "$hugetlb_difference1" \ 555 "Incorrect hugetlb charged to cgroup 1." 556 557 expect_equal "0" "$hugetlb_difference2" \ 558 "Incorrect hugetlb charged to cgroup 2." 559 fi 560 echo 'PASS' 561 562 cleanup 563 echo 564 echo 565 echo 566 echo Test normal case with write, multiple cgroups. 567 echo private=$private, populate=$populate, method=$method, reserve=$reserve 568 run_multiple_cgroup_test "3" "$populate" "-w" "10" "10" "5" \ 569 "$populate" "-w" "10" "10" "10" \ 570 "$method" "$private" "0" "$reserve" 571 572 echo Memory charged to hugtlb1=$hugetlb_difference1 573 echo Memory charged to reservation1=$reserved_difference1 574 echo Memory charged to hugtlb2=$hugetlb_difference2 575 echo Memory charged to reservation2=$reserved_difference2 576 577 expect_equal "3" "$hugetlb_difference1" \ 578 "Incorrect hugetlb charged to cgroup 1." 579 580 expect_equal "3" "$reserved_difference1" \ 581 "Incorrect reservation charged to cgroup 1." 582 583 expect_equal "5" "$hugetlb_difference2" \ 584 "Incorrect hugetlb charged to cgroup 2." 585 586 expect_equal "5" "$reserved_difference2" \ 587 "Incorrected reservation charged to cgroup 2." 588 echo 'PASS' 589 590 cleanup 591 592 done # reserve 593 done # private 594 done # populate 595done # method 596 597if [[ $do_umount ]]; then 598 umount $cgroup_path 599 rmdir $cgroup_path 600fi 601 602echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages