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