xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/vm/hugetlb_reparenting_test.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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