1 #!/bin/bash 2 # SPDX-License-Identifier: GPL-2.0 3 4 # Kselftest framework requirement - SKIP code is 4. 5 ksft_skip=4 6 7 set -e 8 9 if [[ $(id -u) -ne 0 ]]; then 10 echo "This test must be run as root. Skipping..." 11 exit $ksft_skip 12 fi 13 14 nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages) 15 usage_file=usage_in_bytes 16 17 if [[ "$1" == "-cgroup-v2" ]]; then 18 cgroup2=1 19 usage_file=current 20 fi 21 22 23 if [[ $cgroup2 ]]; then 24 CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk '{print $3}') 25 if [[ -z "$CGROUP_ROOT" ]]; then 26 CGROUP_ROOT=/dev/cgroup/memory 27 mount -t cgroup2 none $CGROUP_ROOT 28 do_umount=1 29 fi 30 echo "+hugetlb +memory" >$CGROUP_ROOT/cgroup.subtree_control 31 else 32 CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') 33 if [[ -z "$CGROUP_ROOT" ]]; then 34 CGROUP_ROOT=/dev/cgroup/memory 35 mount -t cgroup memory,hugetlb $CGROUP_ROOT 36 do_umount=1 37 fi 38 fi 39 MNT='/mnt/huge/' 40 41 function get_machine_hugepage_size() { 42 hpz=$(grep -i hugepagesize /proc/meminfo) 43 kb=${hpz:14:-3} 44 mb=$(($kb / 1024)) 45 echo $mb 46 } 47 48 MB=$(get_machine_hugepage_size) 49 50 function cleanup() { 51 echo cleanup 52 set +e 53 rm -rf "$MNT"/* 2>/dev/null 54 umount "$MNT" 2>/dev/null 55 rmdir "$MNT" 2>/dev/null 56 rmdir "$CGROUP_ROOT"/a/b 2>/dev/null 57 rmdir "$CGROUP_ROOT"/a 2>/dev/null 58 rmdir "$CGROUP_ROOT"/test1 2>/dev/null 59 echo 0 >/proc/sys/vm/nr_hugepages 60 set -e 61 } 62 63 function assert_state() { 64 local expected_a="$1" 65 local expected_a_hugetlb="$2" 66 local expected_b="" 67 local expected_b_hugetlb="" 68 69 if [ ! -z ${3:-} ] && [ ! -z ${4:-} ]; then 70 expected_b="$3" 71 expected_b_hugetlb="$4" 72 fi 73 local tolerance=$((5 * 1024 * 1024)) 74 75 local actual_a 76 actual_a="$(cat "$CGROUP_ROOT"/a/memory.$usage_file)" 77 if [[ $actual_a -lt $(($expected_a - $tolerance)) ]] || 78 [[ $actual_a -gt $(($expected_a + $tolerance)) ]]; then 79 echo actual a = $((${actual_a%% *} / 1024 / 1024)) MB 80 echo expected a = $((${expected_a%% *} / 1024 / 1024)) MB 81 echo fail 82 83 cleanup 84 exit 1 85 fi 86 87 local actual_a_hugetlb 88 actual_a_hugetlb="$(cat "$CGROUP_ROOT"/a/hugetlb.${MB}MB.$usage_file)" 89 if [[ $actual_a_hugetlb -lt $(($expected_a_hugetlb - $tolerance)) ]] || 90 [[ $actual_a_hugetlb -gt $(($expected_a_hugetlb + $tolerance)) ]]; then 91 echo actual a hugetlb = $((${actual_a_hugetlb%% *} / 1024 / 1024)) MB 92 echo expected a hugetlb = $((${expected_a_hugetlb%% *} / 1024 / 1024)) MB 93 echo fail 94 95 cleanup 96 exit 1 97 fi 98 99 if [[ -z "$expected_b" || -z "$expected_b_hugetlb" ]]; then 100 return 101 fi 102 103 local actual_b 104 actual_b="$(cat "$CGROUP_ROOT"/a/b/memory.$usage_file)" 105 if [[ $actual_b -lt $(($expected_b - $tolerance)) ]] || 106 [[ $actual_b -gt $(($expected_b + $tolerance)) ]]; then 107 echo actual b = $((${actual_b%% *} / 1024 / 1024)) MB 108 echo expected b = $((${expected_b%% *} / 1024 / 1024)) MB 109 echo fail 110 111 cleanup 112 exit 1 113 fi 114 115 local actual_b_hugetlb 116 actual_b_hugetlb="$(cat "$CGROUP_ROOT"/a/b/hugetlb.${MB}MB.$usage_file)" 117 if [[ $actual_b_hugetlb -lt $(($expected_b_hugetlb - $tolerance)) ]] || 118 [[ $actual_b_hugetlb -gt $(($expected_b_hugetlb + $tolerance)) ]]; then 119 echo actual b hugetlb = $((${actual_b_hugetlb%% *} / 1024 / 1024)) MB 120 echo expected b hugetlb = $((${expected_b_hugetlb%% *} / 1024 / 1024)) MB 121 echo fail 122 123 cleanup 124 exit 1 125 fi 126 } 127 128 function setup() { 129 echo 100 >/proc/sys/vm/nr_hugepages 130 mkdir "$CGROUP_ROOT"/a 131 sleep 1 132 if [[ $cgroup2 ]]; then 133 echo "+hugetlb +memory" >$CGROUP_ROOT/a/cgroup.subtree_control 134 else 135 echo 0 >$CGROUP_ROOT/a/cpuset.mems 136 echo 0 >$CGROUP_ROOT/a/cpuset.cpus 137 fi 138 139 mkdir "$CGROUP_ROOT"/a/b 140 141 if [[ ! $cgroup2 ]]; then 142 echo 0 >$CGROUP_ROOT/a/b/cpuset.mems 143 echo 0 >$CGROUP_ROOT/a/b/cpuset.cpus 144 fi 145 146 mkdir -p "$MNT" 147 mount -t hugetlbfs none "$MNT" 148 } 149 150 write_hugetlbfs() { 151 local cgroup="$1" 152 local path="$2" 153 local size="$3" 154 155 if [[ $cgroup2 ]]; then 156 echo $$ >$CGROUP_ROOT/$cgroup/cgroup.procs 157 else 158 echo 0 >$CGROUP_ROOT/$cgroup/cpuset.mems 159 echo 0 >$CGROUP_ROOT/$cgroup/cpuset.cpus 160 echo $$ >"$CGROUP_ROOT/$cgroup/tasks" 161 fi 162 ./write_to_hugetlbfs -p "$path" -s "$size" -m 0 -o 163 if [[ $cgroup2 ]]; then 164 echo $$ >$CGROUP_ROOT/cgroup.procs 165 else 166 echo $$ >"$CGROUP_ROOT/tasks" 167 fi 168 echo 169 } 170 171 set -e 172 173 size=$((${MB} * 1024 * 1024 * 25)) # 50MB = 25 * 2MB hugepages. 174 175 cleanup 176 177 echo 178 echo 179 echo Test charge, rmdir, uncharge 180 setup 181 echo mkdir 182 mkdir $CGROUP_ROOT/test1 183 184 echo write 185 write_hugetlbfs test1 "$MNT"/test $size 186 187 echo rmdir 188 rmdir $CGROUP_ROOT/test1 189 mkdir $CGROUP_ROOT/test1 190 191 echo uncharge 192 rm -rf /mnt/huge/* 193 194 cleanup 195 196 echo done 197 echo 198 echo 199 if [[ ! $cgroup2 ]]; then 200 echo "Test parent and child hugetlb usage" 201 setup 202 203 echo write 204 write_hugetlbfs a "$MNT"/test $size 205 206 echo Assert memory charged correctly for parent use. 207 assert_state 0 $size 0 0 208 209 write_hugetlbfs a/b "$MNT"/test2 $size 210 211 echo Assert memory charged correctly for child use. 212 assert_state 0 $(($size * 2)) 0 $size 213 214 rmdir "$CGROUP_ROOT"/a/b 215 sleep 5 216 echo Assert memory reparent correctly. 217 assert_state 0 $(($size * 2)) 218 219 rm -rf "$MNT"/* 220 umount "$MNT" 221 echo Assert memory uncharged correctly. 222 assert_state 0 0 223 224 cleanup 225 fi 226 227 echo 228 echo 229 echo "Test child only hugetlb usage" 230 echo setup 231 setup 232 233 echo write 234 write_hugetlbfs a/b "$MNT"/test2 $size 235 236 echo Assert memory charged correctly for child only use. 237 assert_state 0 $(($size)) 0 $size 238 239 rmdir "$CGROUP_ROOT"/a/b 240 echo Assert memory reparent correctly. 241 assert_state 0 $size 242 243 rm -rf "$MNT"/* 244 umount "$MNT" 245 echo Assert memory uncharged correctly. 246 assert_state 0 0 247 248 cleanup 249 250 echo ALL PASS 251 252 if [[ $do_umount ]]; then 253 umount $CGROUP_ROOT 254 rm -rf $CGROUP_ROOT 255 fi 256 257 echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.