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