File Index
Files and directories
Sign in
FILE

hugetlb_reparenting_test.sh

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/mm/hugetlb_reparenting_test.sh BASH
  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=$(mktemp -d)
 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 $nr_hugepgs >/proc/sys/vm/nr_hugepages
 60  set -e
 61}
 62
 63function assert_with_retry() {
 64  local actual_path="$1"
 65  local expected="$2"
 66  local tolerance=$((7 * 1024 * 1024))
 67  local timeout=20
 68  local interval=1
 69  local start_time
 70  local now
 71  local elapsed
 72  local actual
 73
 74  start_time=$(date +%s)
 75
 76  while true; do
 77    actual="$(cat "$actual_path")"
 78
 79    if [[ $actual -ge $(($expected - $tolerance)) ]] &&
 80        [[ $actual -le $(($expected + $tolerance)) ]]; then
 81      return 0
 82    fi
 83
 84    now=$(date +%s)
 85    elapsed=$((now - start_time))
 86
 87    if [[ $elapsed -ge $timeout ]]; then
 88      echo "actual = $((${actual%% *} / 1024 / 1024)) MB"
 89      echo "expected = $((${expected%% *} / 1024 / 1024)) MB"
 90      cleanup
 91      exit 1
 92    fi
 93
 94    sleep $interval
 95  done
 96}
 97
 98function assert_state() {
 99  local expected_a="$1"
100  local expected_a_hugetlb="$2"
101  local expected_b=""
102  local expected_b_hugetlb=""
103
104  if [ ! -z ${3:-} ] && [ ! -z ${4:-} ]; then
105    expected_b="$3"
106    expected_b_hugetlb="$4"
107  fi
108
109  assert_with_retry "$CGROUP_ROOT/a/memory.$usage_file" "$expected_a"
110  assert_with_retry "$CGROUP_ROOT/a/hugetlb.${MB}MB.$usage_file" "$expected_a_hugetlb"
111
112  if [[ -n "$expected_b" && -n "$expected_b_hugetlb" ]]; then
113    assert_with_retry "$CGROUP_ROOT/a/b/memory.$usage_file" "$expected_b"
114    assert_with_retry "$CGROUP_ROOT/a/b/hugetlb.${MB}MB.$usage_file" "$expected_b_hugetlb"
115  fi
116}
117
118function setup() {
119  echo 100 >/proc/sys/vm/nr_hugepages
120  mkdir "$CGROUP_ROOT"/a
121  sleep 1
122  if [[ $cgroup2 ]]; then
123    echo "+hugetlb +memory" >$CGROUP_ROOT/a/cgroup.subtree_control
124  else
125    echo 0 >$CGROUP_ROOT/a/cpuset.mems
126    echo 0 >$CGROUP_ROOT/a/cpuset.cpus
127  fi
128
129  mkdir "$CGROUP_ROOT"/a/b
130
131  if [[ ! $cgroup2 ]]; then
132    echo 0 >$CGROUP_ROOT/a/b/cpuset.mems
133    echo 0 >$CGROUP_ROOT/a/b/cpuset.cpus
134  fi
135
136  mkdir -p "$MNT"
137  mount -t hugetlbfs none "$MNT"
138}
139
140write_hugetlbfs() {
141  local cgroup="$1"
142  local path="$2"
143  local size="$3"
144
145  if [[ $cgroup2 ]]; then
146    echo $$ >$CGROUP_ROOT/$cgroup/cgroup.procs
147  else
148    echo 0 >$CGROUP_ROOT/$cgroup/cpuset.mems
149    echo 0 >$CGROUP_ROOT/$cgroup/cpuset.cpus
150    echo $$ >"$CGROUP_ROOT/$cgroup/tasks"
151  fi
152  ./write_to_hugetlbfs -p "$path" -s "$size" -m 0 -o
153  if [[ $cgroup2 ]]; then
154    echo $$ >$CGROUP_ROOT/cgroup.procs
155  else
156    echo $$ >"$CGROUP_ROOT/tasks"
157  fi
158  echo
159}
160
161set -e
162
163size=$((${MB} * 1024 * 1024 * 25)) # 50MB = 25 * 2MB hugepages.
164
165cleanup
166
167echo
168echo Test charge, rmdir, uncharge
169setup
170echo mkdir
171mkdir $CGROUP_ROOT/test1
172
173echo write
174write_hugetlbfs test1 "$MNT"/test $size
175
176echo rmdir
177rmdir $CGROUP_ROOT/test1
178mkdir $CGROUP_ROOT/test1
179
180echo uncharge
181rm -rf /mnt/huge/*
182
183cleanup
184
185echo done
186echo
187if [[ ! $cgroup2 ]]; then
188  echo "Test parent and child hugetlb usage"
189  setup
190
191  echo write
192  write_hugetlbfs a "$MNT"/test $size
193
194  echo Assert memory charged correctly for parent use.
195  assert_state 0 $size 0 0
196
197  write_hugetlbfs a/b "$MNT"/test2 $size
198
199  echo Assert memory charged correctly for child use.
200  assert_state 0 $(($size * 2)) 0 $size
201
202  rmdir "$CGROUP_ROOT"/a/b
203  echo Assert memory reparent correctly.
204  assert_state 0 $(($size * 2))
205
206  rm -rf "$MNT"/*
207  umount "$MNT"
208  echo Assert memory uncharged correctly.
209  assert_state 0 0
210
211  cleanup
212fi
213
214echo
215echo "Test child only hugetlb usage"
216echo setup
217setup
218
219echo write
220write_hugetlbfs a/b "$MNT"/test2 $size
221
222echo Assert memory charged correctly for child only use.
223assert_state 0 $(($size)) 0 $size
224
225rmdir "$CGROUP_ROOT"/a/b
226echo Assert memory reparent correctly.
227assert_state 0 $size
228
229rm -rf "$MNT"/*
230umount "$MNT"
231echo Assert memory uncharged correctly.
232assert_state 0 0
233
234cleanup
235
236echo ALL PASS
237
238if [[ $do_umount ]]; then
239  umount $CGROUP_ROOT
240  rm -rf $CGROUP_ROOT
241fi
242
243echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages
~/ Read-only file preview.