brintos

brintos / linux-shallow public Read only

0
0
Text · 17.1 KiB · 67df7b4 Raw
589 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4# Kselftest framework requirement - SKIP code is 4.5ksft_skip=46 7set -e8 9if [[ $(id -u) -ne 0 ]]; then10  echo "This test must be run as root. Skipping..."11  exit $ksft_skip12fi13 14nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)15 16fault_limit_file=limit_in_bytes17reservation_limit_file=rsvd.limit_in_bytes18fault_usage_file=usage_in_bytes19reservation_usage_file=rsvd.usage_in_bytes20 21if [[ "$1" == "-cgroup-v2" ]]; then22  cgroup2=123  fault_limit_file=max24  reservation_limit_file=rsvd.max25  fault_usage_file=current26  reservation_usage_file=rsvd.current27fi28 29if [[ $cgroup2 ]]; then30  cgroup_path=$(mount -t cgroup2 | head -1 | awk '{print $3}')31  if [[ -z "$cgroup_path" ]]; then32    cgroup_path=/dev/cgroup/memory33    mount -t cgroup2 none $cgroup_path34    do_umount=135  fi36  echo "+hugetlb" >$cgroup_path/cgroup.subtree_control37else38  cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}')39  if [[ -z "$cgroup_path" ]]; then40    cgroup_path=/dev/cgroup/memory41    mount -t cgroup memory,hugetlb $cgroup_path42    do_umount=143  fi44fi45export cgroup_path46 47function cleanup() {48  if [[ $cgroup2 ]]; then49    echo $$ >$cgroup_path/cgroup.procs50  else51    echo $$ >$cgroup_path/tasks52  fi53 54  if [[ -e /mnt/huge ]]; then55    rm -rf /mnt/huge/*56    umount /mnt/huge || echo error57    rmdir /mnt/huge58  fi59  if [[ -e $cgroup_path/hugetlb_cgroup_test ]]; then60    rmdir $cgroup_path/hugetlb_cgroup_test61  fi62  if [[ -e $cgroup_path/hugetlb_cgroup_test1 ]]; then63    rmdir $cgroup_path/hugetlb_cgroup_test164  fi65  if [[ -e $cgroup_path/hugetlb_cgroup_test2 ]]; then66    rmdir $cgroup_path/hugetlb_cgroup_test267  fi68  echo 0 >/proc/sys/vm/nr_hugepages69  echo CLEANUP DONE70}71 72function expect_equal() {73  local expected="$1"74  local actual="$2"75  local error="$3"76 77  if [[ "$expected" != "$actual" ]]; then78    echo "expected ($expected) != actual ($actual): $3"79    cleanup80    exit 181  fi82}83 84function get_machine_hugepage_size() {85  hpz=$(grep -i hugepagesize /proc/meminfo)86  kb=${hpz:14:-3}87  mb=$(($kb / 1024))88  echo $mb89}90 91MB=$(get_machine_hugepage_size)92 93function setup_cgroup() {94  local name="$1"95  local cgroup_limit="$2"96  local reservation_limit="$3"97 98  mkdir $cgroup_path/$name99 100  echo writing cgroup limit: "$cgroup_limit"101  echo "$cgroup_limit" >$cgroup_path/$name/hugetlb.${MB}MB.$fault_limit_file102 103  echo writing reseravation limit: "$reservation_limit"104  echo "$reservation_limit" > \105    $cgroup_path/$name/hugetlb.${MB}MB.$reservation_limit_file106 107  if [ -e "$cgroup_path/$name/cpuset.cpus" ]; then108    echo 0 >$cgroup_path/$name/cpuset.cpus109  fi110  if [ -e "$cgroup_path/$name/cpuset.mems" ]; then111    echo 0 >$cgroup_path/$name/cpuset.mems112  fi113}114 115function wait_for_hugetlb_memory_to_get_depleted() {116  local cgroup="$1"117  local path="$cgroup_path/$cgroup/hugetlb.${MB}MB.$reservation_usage_file"118  # Wait for hugetlbfs memory to get depleted.119  while [ $(cat $path) != 0 ]; do120    echo Waiting for hugetlb memory to get depleted.121    cat $path122    sleep 0.5123  done124}125 126function wait_for_hugetlb_memory_to_get_reserved() {127  local cgroup="$1"128  local size="$2"129 130  local path="$cgroup_path/$cgroup/hugetlb.${MB}MB.$reservation_usage_file"131  # Wait for hugetlbfs memory to get written.132  while [ $(cat $path) != $size ]; do133    echo Waiting for hugetlb memory reservation to reach size $size.134    cat $path135    sleep 0.5136  done137}138 139function wait_for_hugetlb_memory_to_get_written() {140  local cgroup="$1"141  local size="$2"142 143  local path="$cgroup_path/$cgroup/hugetlb.${MB}MB.$fault_usage_file"144  # Wait for hugetlbfs memory to get written.145  while [ $(cat $path) != $size ]; do146    echo Waiting for hugetlb memory to reach size $size.147    cat $path148    sleep 0.5149  done150}151 152function write_hugetlbfs_and_get_usage() {153  local cgroup="$1"154  local size="$2"155  local populate="$3"156  local write="$4"157  local path="$5"158  local method="$6"159  local private="$7"160  local expect_failure="$8"161  local reserve="$9"162 163  # Function return values.164  reservation_failed=0165  oom_killed=0166  hugetlb_difference=0167  reserved_difference=0168 169  local hugetlb_usage=$cgroup_path/$cgroup/hugetlb.${MB}MB.$fault_usage_file170  local reserved_usage=$cgroup_path/$cgroup/hugetlb.${MB}MB.$reservation_usage_file171 172  local hugetlb_before=$(cat $hugetlb_usage)173  local reserved_before=$(cat $reserved_usage)174 175  echo176  echo Starting:177  echo hugetlb_usage="$hugetlb_before"178  echo reserved_usage="$reserved_before"179  echo expect_failure is "$expect_failure"180 181  output=$(mktemp)182  set +e183  if [[ "$method" == "1" ]] || [[ "$method" == 2 ]] ||184    [[ "$private" == "-r" ]] && [[ "$expect_failure" != 1 ]]; then185 186    bash write_hugetlb_memory.sh "$size" "$populate" "$write" \187      "$cgroup" "$path" "$method" "$private" "-l" "$reserve" 2>&1 | tee $output &188 189    local write_result=$?190    local write_pid=$!191 192    until grep -q -i "DONE" $output; do193      echo waiting for DONE signal.194      if ! ps $write_pid > /dev/null195      then196        echo "FAIL: The write died"197        cleanup198        exit 1199      fi200      sleep 0.5201    done202 203    echo ================= write_hugetlb_memory.sh output is:204    cat $output205    echo ================= end output.206 207    if [[ "$populate" == "-o" ]] || [[ "$write" == "-w" ]]; then208      wait_for_hugetlb_memory_to_get_written "$cgroup" "$size"209    elif [[ "$reserve" != "-n" ]]; then210      wait_for_hugetlb_memory_to_get_reserved "$cgroup" "$size"211    else212      # This case doesn't produce visible effects, but we still have213      # to wait for the async process to start and execute...214      sleep 0.5215    fi216 217    echo write_result is $write_result218  else219    bash write_hugetlb_memory.sh "$size" "$populate" "$write" \220      "$cgroup" "$path" "$method" "$private" "$reserve"221    local write_result=$?222 223    if [[ "$reserve" != "-n" ]]; then224      wait_for_hugetlb_memory_to_get_reserved "$cgroup" "$size"225    fi226  fi227  set -e228 229  if [[ "$write_result" == 1 ]]; then230    reservation_failed=1231  fi232 233  # On linus/master, the above process gets SIGBUS'd on oomkill, with234  # return code 135. On earlier kernels, it gets actual oomkill, with return235  # code 137, so just check for both conditions in case we're testing236  # against an earlier kernel.237  if [[ "$write_result" == 135 ]] || [[ "$write_result" == 137 ]]; then238    oom_killed=1239  fi240 241  local hugetlb_after=$(cat $hugetlb_usage)242  local reserved_after=$(cat $reserved_usage)243 244  echo After write:245  echo hugetlb_usage="$hugetlb_after"246  echo reserved_usage="$reserved_after"247 248  hugetlb_difference=$(($hugetlb_after - $hugetlb_before))249  reserved_difference=$(($reserved_after - $reserved_before))250}251 252function cleanup_hugetlb_memory() {253  set +e254  local cgroup="$1"255  if [[ "$(pgrep -f write_to_hugetlbfs)" != "" ]]; then256    echo killing write_to_hugetlbfs257    killall -2 --wait write_to_hugetlbfs258    wait_for_hugetlb_memory_to_get_depleted $cgroup259  fi260  set -e261 262  if [[ -e /mnt/huge ]]; then263    rm -rf /mnt/huge/*264    umount /mnt/huge265    rmdir /mnt/huge266  fi267}268 269function run_test() {270  local size=$(($1 * ${MB} * 1024 * 1024))271  local populate="$2"272  local write="$3"273  local cgroup_limit=$(($4 * ${MB} * 1024 * 1024))274  local reservation_limit=$(($5 * ${MB} * 1024 * 1024))275  local nr_hugepages="$6"276  local method="$7"277  local private="$8"278  local expect_failure="$9"279  local reserve="${10}"280 281  # Function return values.282  hugetlb_difference=0283  reserved_difference=0284  reservation_failed=0285  oom_killed=0286 287  echo nr hugepages = "$nr_hugepages"288  echo "$nr_hugepages" >/proc/sys/vm/nr_hugepages289 290  setup_cgroup "hugetlb_cgroup_test" "$cgroup_limit" "$reservation_limit"291 292  mkdir -p /mnt/huge293  mount -t hugetlbfs -o pagesize=${MB}M,size=256M none /mnt/huge294 295  write_hugetlbfs_and_get_usage "hugetlb_cgroup_test" "$size" "$populate" \296    "$write" "/mnt/huge/test" "$method" "$private" "$expect_failure" \297    "$reserve"298 299  cleanup_hugetlb_memory "hugetlb_cgroup_test"300 301  local final_hugetlb=$(cat $cgroup_path/hugetlb_cgroup_test/hugetlb.${MB}MB.$fault_usage_file)302  local final_reservation=$(cat $cgroup_path/hugetlb_cgroup_test/hugetlb.${MB}MB.$reservation_usage_file)303 304  echo $hugetlb_difference305  echo $reserved_difference306  expect_equal "0" "$final_hugetlb" "final hugetlb is not zero"307  expect_equal "0" "$final_reservation" "final reservation is not zero"308}309 310function run_multiple_cgroup_test() {311  local size1="$1"312  local populate1="$2"313  local write1="$3"314  local cgroup_limit1="$4"315  local reservation_limit1="$5"316 317  local size2="$6"318  local populate2="$7"319  local write2="$8"320  local cgroup_limit2="$9"321  local reservation_limit2="${10}"322 323  local nr_hugepages="${11}"324  local method="${12}"325  local private="${13}"326  local expect_failure="${14}"327  local reserve="${15}"328 329  # Function return values.330  hugetlb_difference1=0331  reserved_difference1=0332  reservation_failed1=0333  oom_killed1=0334 335  hugetlb_difference2=0336  reserved_difference2=0337  reservation_failed2=0338  oom_killed2=0339 340  echo nr hugepages = "$nr_hugepages"341  echo "$nr_hugepages" >/proc/sys/vm/nr_hugepages342 343  setup_cgroup "hugetlb_cgroup_test1" "$cgroup_limit1" "$reservation_limit1"344  setup_cgroup "hugetlb_cgroup_test2" "$cgroup_limit2" "$reservation_limit2"345 346  mkdir -p /mnt/huge347  mount -t hugetlbfs -o pagesize=${MB}M,size=256M none /mnt/huge348 349  write_hugetlbfs_and_get_usage "hugetlb_cgroup_test1" "$size1" \350    "$populate1" "$write1" "/mnt/huge/test1" "$method" "$private" \351    "$expect_failure" "$reserve"352 353  hugetlb_difference1=$hugetlb_difference354  reserved_difference1=$reserved_difference355  reservation_failed1=$reservation_failed356  oom_killed1=$oom_killed357 358  local cgroup1_hugetlb_usage=$cgroup_path/hugetlb_cgroup_test1/hugetlb.${MB}MB.$fault_usage_file359  local cgroup1_reservation_usage=$cgroup_path/hugetlb_cgroup_test1/hugetlb.${MB}MB.$reservation_usage_file360  local cgroup2_hugetlb_usage=$cgroup_path/hugetlb_cgroup_test2/hugetlb.${MB}MB.$fault_usage_file361  local cgroup2_reservation_usage=$cgroup_path/hugetlb_cgroup_test2/hugetlb.${MB}MB.$reservation_usage_file362 363  local usage_before_second_write=$(cat $cgroup1_hugetlb_usage)364  local reservation_usage_before_second_write=$(cat $cgroup1_reservation_usage)365 366  write_hugetlbfs_and_get_usage "hugetlb_cgroup_test2" "$size2" \367    "$populate2" "$write2" "/mnt/huge/test2" "$method" "$private" \368    "$expect_failure" "$reserve"369 370  hugetlb_difference2=$hugetlb_difference371  reserved_difference2=$reserved_difference372  reservation_failed2=$reservation_failed373  oom_killed2=$oom_killed374 375  expect_equal "$usage_before_second_write" \376    "$(cat $cgroup1_hugetlb_usage)" "Usage changed."377  expect_equal "$reservation_usage_before_second_write" \378    "$(cat $cgroup1_reservation_usage)" "Reservation usage changed."379 380  cleanup_hugetlb_memory381 382  local final_hugetlb=$(cat $cgroup1_hugetlb_usage)383  local final_reservation=$(cat $cgroup1_reservation_usage)384 385  expect_equal "0" "$final_hugetlb" \386    "hugetlbt_cgroup_test1 final hugetlb is not zero"387  expect_equal "0" "$final_reservation" \388    "hugetlbt_cgroup_test1 final reservation is not zero"389 390  local final_hugetlb=$(cat $cgroup2_hugetlb_usage)391  local final_reservation=$(cat $cgroup2_reservation_usage)392 393  expect_equal "0" "$final_hugetlb" \394    "hugetlb_cgroup_test2 final hugetlb is not zero"395  expect_equal "0" "$final_reservation" \396    "hugetlb_cgroup_test2 final reservation is not zero"397}398 399cleanup400 401for populate in "" "-o"; do402  for method in 0 1 2; do403    for private in "" "-r"; do404      for reserve in "" "-n"; do405 406        # Skip mmap(MAP_HUGETLB | MAP_SHARED). Doesn't seem to be supported.407        if [[ "$method" == 1 ]] && [[ "$private" == "" ]]; then408          continue409        fi410 411        # Skip populated shmem tests. Doesn't seem to be supported.412        if [[ "$method" == 2"" ]] && [[ "$populate" == "-o" ]]; then413          continue414        fi415 416        if [[ "$method" == 2"" ]] && [[ "$reserve" == "-n" ]]; then417          continue418        fi419 420        cleanup421        echo422        echo423        echo424        echo Test normal case.425        echo private=$private, populate=$populate, method=$method, reserve=$reserve426        run_test 5 "$populate" "" 10 10 10 "$method" "$private" "0" "$reserve"427 428        echo Memory charged to hugtlb=$hugetlb_difference429        echo Memory charged to reservation=$reserved_difference430 431        if [[ "$populate" == "-o" ]]; then432          expect_equal "$((5 * $MB * 1024 * 1024))" "$hugetlb_difference" \433            "Reserved memory charged to hugetlb cgroup."434        else435          expect_equal "0" "$hugetlb_difference" \436            "Reserved memory charged to hugetlb cgroup."437        fi438 439        if [[ "$reserve" != "-n" ]] || [[ "$populate" == "-o" ]]; then440          expect_equal "$((5 * $MB * 1024 * 1024))" "$reserved_difference" \441            "Reserved memory not charged to reservation usage."442        else443          expect_equal "0" "$reserved_difference" \444            "Reserved memory not charged to reservation usage."445        fi446 447        echo 'PASS'448 449        cleanup450        echo451        echo452        echo453        echo Test normal case with write.454        echo private=$private, populate=$populate, method=$method, reserve=$reserve455        run_test 5 "$populate" '-w' 5 5 10 "$method" "$private" "0" "$reserve"456 457        echo Memory charged to hugtlb=$hugetlb_difference458        echo Memory charged to reservation=$reserved_difference459 460        expect_equal "$((5 * $MB * 1024 * 1024))" "$hugetlb_difference" \461          "Reserved memory charged to hugetlb cgroup."462 463        expect_equal "$((5 * $MB * 1024 * 1024))" "$reserved_difference" \464          "Reserved memory not charged to reservation usage."465 466        echo 'PASS'467 468        cleanup469        continue470        echo471        echo472        echo473        echo Test more than reservation case.474        echo private=$private, populate=$populate, method=$method, reserve=$reserve475 476        if [ "$reserve" != "-n" ]; then477          run_test "5" "$populate" '' "10" "2" "10" "$method" "$private" "1" \478            "$reserve"479 480          expect_equal "1" "$reservation_failed" "Reservation succeeded."481        fi482 483        echo 'PASS'484 485        cleanup486 487        echo488        echo489        echo490        echo Test more than cgroup limit case.491        echo private=$private, populate=$populate, method=$method, reserve=$reserve492 493        # Not sure if shm memory can be cleaned up when the process gets sigbus'd.494        if [[ "$method" != 2 ]]; then495          run_test 5 "$populate" "-w" 2 10 10 "$method" "$private" "1" "$reserve"496 497          expect_equal "1" "$oom_killed" "Not oom killed."498        fi499        echo 'PASS'500 501        cleanup502 503        echo504        echo505        echo506        echo Test normal case, multiple cgroups.507        echo private=$private, populate=$populate, method=$method, reserve=$reserve508        run_multiple_cgroup_test "3" "$populate" "" "10" "10" "5" \509          "$populate" "" "10" "10" "10" \510          "$method" "$private" "0" "$reserve"511 512        echo Memory charged to hugtlb1=$hugetlb_difference1513        echo Memory charged to reservation1=$reserved_difference1514        echo Memory charged to hugtlb2=$hugetlb_difference2515        echo Memory charged to reservation2=$reserved_difference2516 517        if [[ "$reserve" != "-n" ]] || [[ "$populate" == "-o" ]]; then518          expect_equal "3" "$reserved_difference1" \519            "Incorrect reservations charged to cgroup 1."520 521          expect_equal "5" "$reserved_difference2" \522            "Incorrect reservation charged to cgroup 2."523 524        else525          expect_equal "0" "$reserved_difference1" \526            "Incorrect reservations charged to cgroup 1."527 528          expect_equal "0" "$reserved_difference2" \529            "Incorrect reservation charged to cgroup 2."530        fi531 532        if [[ "$populate" == "-o" ]]; then533          expect_equal "3" "$hugetlb_difference1" \534            "Incorrect hugetlb charged to cgroup 1."535 536          expect_equal "5" "$hugetlb_difference2" \537            "Incorrect hugetlb charged to cgroup 2."538 539        else540          expect_equal "0" "$hugetlb_difference1" \541            "Incorrect hugetlb charged to cgroup 1."542 543          expect_equal "0" "$hugetlb_difference2" \544            "Incorrect hugetlb charged to cgroup 2."545        fi546        echo 'PASS'547 548        cleanup549        echo550        echo551        echo552        echo Test normal case with write, multiple cgroups.553        echo private=$private, populate=$populate, method=$method, reserve=$reserve554        run_multiple_cgroup_test "3" "$populate" "-w" "10" "10" "5" \555          "$populate" "-w" "10" "10" "10" \556          "$method" "$private" "0" "$reserve"557 558        echo Memory charged to hugtlb1=$hugetlb_difference1559        echo Memory charged to reservation1=$reserved_difference1560        echo Memory charged to hugtlb2=$hugetlb_difference2561        echo Memory charged to reservation2=$reserved_difference2562 563        expect_equal "3" "$hugetlb_difference1" \564          "Incorrect hugetlb charged to cgroup 1."565 566        expect_equal "3" "$reserved_difference1" \567          "Incorrect reservation charged to cgroup 1."568 569        expect_equal "5" "$hugetlb_difference2" \570          "Incorrect hugetlb charged to cgroup 2."571 572        expect_equal "5" "$reserved_difference2" \573          "Incorrected reservation charged to cgroup 2."574        echo 'PASS'575 576        cleanup577 578      done # reserve579    done   # private580  done     # populate581done       # method582 583if [[ $do_umount ]]; then584  umount $cgroup_path585  rmdir $cgroup_path586fi587 588echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages589