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