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