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