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