258 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)15usage_file=usage_in_bytes16 17if [[ "$1" == "-cgroup-v2" ]]; then18 cgroup2=119 usage_file=current20fi21 22 23if [[ $cgroup2 ]]; then24 CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk '{print $3}')25 if [[ -z "$CGROUP_ROOT" ]]; then26 CGROUP_ROOT=/dev/cgroup/memory27 mount -t cgroup2 none $CGROUP_ROOT28 do_umount=129 fi30 echo "+hugetlb +memory" >$CGROUP_ROOT/cgroup.subtree_control31else32 CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}')33 if [[ -z "$CGROUP_ROOT" ]]; then34 CGROUP_ROOT=/dev/cgroup/memory35 mount -t cgroup memory,hugetlb $CGROUP_ROOT36 do_umount=137 fi38fi39MNT='/mnt/huge/'40 41function get_machine_hugepage_size() {42 hpz=$(grep -i hugepagesize /proc/meminfo)43 kb=${hpz:14:-3}44 mb=$(($kb / 1024))45 echo $mb46}47 48MB=$(get_machine_hugepage_size)49 50function cleanup() {51 echo cleanup52 set +e53 rm -rf "$MNT"/* 2>/dev/null54 umount "$MNT" 2>/dev/null55 rmdir "$MNT" 2>/dev/null56 rmdir "$CGROUP_ROOT"/a/b 2>/dev/null57 rmdir "$CGROUP_ROOT"/a 2>/dev/null58 rmdir "$CGROUP_ROOT"/test1 2>/dev/null59 echo 0 >/proc/sys/vm/nr_hugepages60 set -e61}62 63function 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:-} ]; then70 expected_b="$3"71 expected_b_hugetlb="$4"72 fi73 local tolerance=$((5 * 1024 * 1024))74 75 local actual_a76 actual_a="$(cat "$CGROUP_ROOT"/a/memory.$usage_file)"77 if [[ $actual_a -lt $(($expected_a - $tolerance)) ]] ||78 [[ $actual_a -gt $(($expected_a + $tolerance)) ]]; then79 echo actual a = $((${actual_a%% *} / 1024 / 1024)) MB80 echo expected a = $((${expected_a%% *} / 1024 / 1024)) MB81 echo fail82 83 cleanup84 exit 185 fi86 87 local actual_a_hugetlb88 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)) ]]; then91 echo actual a hugetlb = $((${actual_a_hugetlb%% *} / 1024 / 1024)) MB92 echo expected a hugetlb = $((${expected_a_hugetlb%% *} / 1024 / 1024)) MB93 echo fail94 95 cleanup96 exit 197 fi98 99 if [[ -z "$expected_b" || -z "$expected_b_hugetlb" ]]; then100 return101 fi102 103 local actual_b104 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)) ]]; then107 echo actual b = $((${actual_b%% *} / 1024 / 1024)) MB108 echo expected b = $((${expected_b%% *} / 1024 / 1024)) MB109 echo fail110 111 cleanup112 exit 1113 fi114 115 local actual_b_hugetlb116 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)) ]]; then119 echo actual b hugetlb = $((${actual_b_hugetlb%% *} / 1024 / 1024)) MB120 echo expected b hugetlb = $((${expected_b_hugetlb%% *} / 1024 / 1024)) MB121 echo fail122 123 cleanup124 exit 1125 fi126}127 128function setup() {129 echo 100 >/proc/sys/vm/nr_hugepages130 mkdir "$CGROUP_ROOT"/a131 sleep 1132 if [[ $cgroup2 ]]; then133 echo "+hugetlb +memory" >$CGROUP_ROOT/a/cgroup.subtree_control134 else135 echo 0 >$CGROUP_ROOT/a/cpuset.mems136 echo 0 >$CGROUP_ROOT/a/cpuset.cpus137 fi138 139 mkdir "$CGROUP_ROOT"/a/b140 141 if [[ ! $cgroup2 ]]; then142 echo 0 >$CGROUP_ROOT/a/b/cpuset.mems143 echo 0 >$CGROUP_ROOT/a/b/cpuset.cpus144 fi145 146 mkdir -p "$MNT"147 mount -t hugetlbfs none "$MNT"148}149 150write_hugetlbfs() {151 local cgroup="$1"152 local path="$2"153 local size="$3"154 155 if [[ $cgroup2 ]]; then156 echo $$ >$CGROUP_ROOT/$cgroup/cgroup.procs157 else158 echo 0 >$CGROUP_ROOT/$cgroup/cpuset.mems159 echo 0 >$CGROUP_ROOT/$cgroup/cpuset.cpus160 echo $$ >"$CGROUP_ROOT/$cgroup/tasks"161 fi162 ./write_to_hugetlbfs -p "$path" -s "$size" -m 0 -o163 if [[ $cgroup2 ]]; then164 echo $$ >$CGROUP_ROOT/cgroup.procs165 else166 echo $$ >"$CGROUP_ROOT/tasks"167 fi168 echo169}170 171set -e172 173size=$((${MB} * 1024 * 1024 * 25)) # 50MB = 25 * 2MB hugepages.174 175cleanup176 177echo178echo179echo Test charge, rmdir, uncharge180setup181echo mkdir182mkdir $CGROUP_ROOT/test1183 184echo write185write_hugetlbfs test1 "$MNT"/test $size186 187echo rmdir188rmdir $CGROUP_ROOT/test1189mkdir $CGROUP_ROOT/test1190 191echo uncharge192rm -rf /mnt/huge/*193 194cleanup195 196echo done197echo198echo199if [[ ! $cgroup2 ]]; then200 echo "Test parent and child hugetlb usage"201 setup202 203 echo write204 write_hugetlbfs a "$MNT"/test $size205 206 echo Assert memory charged correctly for parent use.207 assert_state 0 $size 0 0208 209 write_hugetlbfs a/b "$MNT"/test2 $size210 211 echo Assert memory charged correctly for child use.212 assert_state 0 $(($size * 2)) 0 $size213 214 rmdir "$CGROUP_ROOT"/a/b215 sleep 5216 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 0223 224 cleanup225fi226 227echo228echo229echo "Test child only hugetlb usage"230echo setup231setup232 233echo write234write_hugetlbfs a/b "$MNT"/test2 $size235 236echo Assert memory charged correctly for child only use.237assert_state 0 $(($size)) 0 $size238 239rmdir "$CGROUP_ROOT"/a/b240echo Assert memory reparent correctly.241assert_state 0 $size242 243rm -rf "$MNT"/*244umount "$MNT"245echo Assert memory uncharged correctly.246assert_state 0 0247 248cleanup249 250echo ALL PASS251 252if [[ $do_umount ]]; then253 umount $CGROUP_ROOT254 rm -rf $CGROUP_ROOT255fi256 257echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages258