162306a36Sopenharmony_ci#!/bin/bash
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci# Kselftest framework requirement - SKIP code is 4.
562306a36Sopenharmony_ciksft_skip=4
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciset -e
862306a36Sopenharmony_ci
962306a36Sopenharmony_ciif [[ $(id -u) -ne 0 ]]; then
1062306a36Sopenharmony_ci  echo "This test must be run as root. Skipping..."
1162306a36Sopenharmony_ci  exit $ksft_skip
1262306a36Sopenharmony_cifi
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ciusage_file=usage_in_bytes
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciif [[ "$1" == "-cgroup-v2" ]]; then
1762306a36Sopenharmony_ci  cgroup2=1
1862306a36Sopenharmony_ci  usage_file=current
1962306a36Sopenharmony_cifi
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciif [[ $cgroup2 ]]; then
2362306a36Sopenharmony_ci  CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk '{print $3}')
2462306a36Sopenharmony_ci  if [[ -z "$CGROUP_ROOT" ]]; then
2562306a36Sopenharmony_ci    CGROUP_ROOT=/dev/cgroup/memory
2662306a36Sopenharmony_ci    mount -t cgroup2 none $CGROUP_ROOT
2762306a36Sopenharmony_ci    do_umount=1
2862306a36Sopenharmony_ci  fi
2962306a36Sopenharmony_ci  echo "+hugetlb +memory" >$CGROUP_ROOT/cgroup.subtree_control
3062306a36Sopenharmony_cielse
3162306a36Sopenharmony_ci  CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}')
3262306a36Sopenharmony_ci  if [[ -z "$CGROUP_ROOT" ]]; then
3362306a36Sopenharmony_ci    CGROUP_ROOT=/dev/cgroup/memory
3462306a36Sopenharmony_ci    mount -t cgroup memory,hugetlb $CGROUP_ROOT
3562306a36Sopenharmony_ci    do_umount=1
3662306a36Sopenharmony_ci  fi
3762306a36Sopenharmony_cifi
3862306a36Sopenharmony_ciMNT='/mnt/huge/'
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cifunction get_machine_hugepage_size() {
4162306a36Sopenharmony_ci  hpz=$(grep -i hugepagesize /proc/meminfo)
4262306a36Sopenharmony_ci  kb=${hpz:14:-3}
4362306a36Sopenharmony_ci  mb=$(($kb / 1024))
4462306a36Sopenharmony_ci  echo $mb
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ciMB=$(get_machine_hugepage_size)
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cifunction cleanup() {
5062306a36Sopenharmony_ci  echo cleanup
5162306a36Sopenharmony_ci  set +e
5262306a36Sopenharmony_ci  rm -rf "$MNT"/* 2>/dev/null
5362306a36Sopenharmony_ci  umount "$MNT" 2>/dev/null
5462306a36Sopenharmony_ci  rmdir "$MNT" 2>/dev/null
5562306a36Sopenharmony_ci  rmdir "$CGROUP_ROOT"/a/b 2>/dev/null
5662306a36Sopenharmony_ci  rmdir "$CGROUP_ROOT"/a 2>/dev/null
5762306a36Sopenharmony_ci  rmdir "$CGROUP_ROOT"/test1 2>/dev/null
5862306a36Sopenharmony_ci  echo 0 >/proc/sys/vm/nr_hugepages
5962306a36Sopenharmony_ci  set -e
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cifunction assert_state() {
6362306a36Sopenharmony_ci  local expected_a="$1"
6462306a36Sopenharmony_ci  local expected_a_hugetlb="$2"
6562306a36Sopenharmony_ci  local expected_b=""
6662306a36Sopenharmony_ci  local expected_b_hugetlb=""
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci  if [ ! -z ${3:-} ] && [ ! -z ${4:-} ]; then
6962306a36Sopenharmony_ci    expected_b="$3"
7062306a36Sopenharmony_ci    expected_b_hugetlb="$4"
7162306a36Sopenharmony_ci  fi
7262306a36Sopenharmony_ci  local tolerance=$((5 * 1024 * 1024))
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci  local actual_a
7562306a36Sopenharmony_ci  actual_a="$(cat "$CGROUP_ROOT"/a/memory.$usage_file)"
7662306a36Sopenharmony_ci  if [[ $actual_a -lt $(($expected_a - $tolerance)) ]] ||
7762306a36Sopenharmony_ci    [[ $actual_a -gt $(($expected_a + $tolerance)) ]]; then
7862306a36Sopenharmony_ci    echo actual a = $((${actual_a%% *} / 1024 / 1024)) MB
7962306a36Sopenharmony_ci    echo expected a = $((${expected_a%% *} / 1024 / 1024)) MB
8062306a36Sopenharmony_ci    echo fail
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci    cleanup
8362306a36Sopenharmony_ci    exit 1
8462306a36Sopenharmony_ci  fi
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci  local actual_a_hugetlb
8762306a36Sopenharmony_ci  actual_a_hugetlb="$(cat "$CGROUP_ROOT"/a/hugetlb.${MB}MB.$usage_file)"
8862306a36Sopenharmony_ci  if [[ $actual_a_hugetlb -lt $(($expected_a_hugetlb - $tolerance)) ]] ||
8962306a36Sopenharmony_ci    [[ $actual_a_hugetlb -gt $(($expected_a_hugetlb + $tolerance)) ]]; then
9062306a36Sopenharmony_ci    echo actual a hugetlb = $((${actual_a_hugetlb%% *} / 1024 / 1024)) MB
9162306a36Sopenharmony_ci    echo expected a hugetlb = $((${expected_a_hugetlb%% *} / 1024 / 1024)) MB
9262306a36Sopenharmony_ci    echo fail
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci    cleanup
9562306a36Sopenharmony_ci    exit 1
9662306a36Sopenharmony_ci  fi
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci  if [[ -z "$expected_b" || -z "$expected_b_hugetlb" ]]; then
9962306a36Sopenharmony_ci    return
10062306a36Sopenharmony_ci  fi
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci  local actual_b
10362306a36Sopenharmony_ci  actual_b="$(cat "$CGROUP_ROOT"/a/b/memory.$usage_file)"
10462306a36Sopenharmony_ci  if [[ $actual_b -lt $(($expected_b - $tolerance)) ]] ||
10562306a36Sopenharmony_ci    [[ $actual_b -gt $(($expected_b + $tolerance)) ]]; then
10662306a36Sopenharmony_ci    echo actual b = $((${actual_b%% *} / 1024 / 1024)) MB
10762306a36Sopenharmony_ci    echo expected b = $((${expected_b%% *} / 1024 / 1024)) MB
10862306a36Sopenharmony_ci    echo fail
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci    cleanup
11162306a36Sopenharmony_ci    exit 1
11262306a36Sopenharmony_ci  fi
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci  local actual_b_hugetlb
11562306a36Sopenharmony_ci  actual_b_hugetlb="$(cat "$CGROUP_ROOT"/a/b/hugetlb.${MB}MB.$usage_file)"
11662306a36Sopenharmony_ci  if [[ $actual_b_hugetlb -lt $(($expected_b_hugetlb - $tolerance)) ]] ||
11762306a36Sopenharmony_ci    [[ $actual_b_hugetlb -gt $(($expected_b_hugetlb + $tolerance)) ]]; then
11862306a36Sopenharmony_ci    echo actual b hugetlb = $((${actual_b_hugetlb%% *} / 1024 / 1024)) MB
11962306a36Sopenharmony_ci    echo expected b hugetlb = $((${expected_b_hugetlb%% *} / 1024 / 1024)) MB
12062306a36Sopenharmony_ci    echo fail
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci    cleanup
12362306a36Sopenharmony_ci    exit 1
12462306a36Sopenharmony_ci  fi
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cifunction setup() {
12862306a36Sopenharmony_ci  echo 100 >/proc/sys/vm/nr_hugepages
12962306a36Sopenharmony_ci  mkdir "$CGROUP_ROOT"/a
13062306a36Sopenharmony_ci  sleep 1
13162306a36Sopenharmony_ci  if [[ $cgroup2 ]]; then
13262306a36Sopenharmony_ci    echo "+hugetlb +memory" >$CGROUP_ROOT/a/cgroup.subtree_control
13362306a36Sopenharmony_ci  else
13462306a36Sopenharmony_ci    echo 0 >$CGROUP_ROOT/a/cpuset.mems
13562306a36Sopenharmony_ci    echo 0 >$CGROUP_ROOT/a/cpuset.cpus
13662306a36Sopenharmony_ci  fi
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci  mkdir "$CGROUP_ROOT"/a/b
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci  if [[ ! $cgroup2 ]]; then
14162306a36Sopenharmony_ci    echo 0 >$CGROUP_ROOT/a/b/cpuset.mems
14262306a36Sopenharmony_ci    echo 0 >$CGROUP_ROOT/a/b/cpuset.cpus
14362306a36Sopenharmony_ci  fi
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci  mkdir -p "$MNT"
14662306a36Sopenharmony_ci  mount -t hugetlbfs none "$MNT"
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ciwrite_hugetlbfs() {
15062306a36Sopenharmony_ci  local cgroup="$1"
15162306a36Sopenharmony_ci  local path="$2"
15262306a36Sopenharmony_ci  local size="$3"
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci  if [[ $cgroup2 ]]; then
15562306a36Sopenharmony_ci    echo $$ >$CGROUP_ROOT/$cgroup/cgroup.procs
15662306a36Sopenharmony_ci  else
15762306a36Sopenharmony_ci    echo 0 >$CGROUP_ROOT/$cgroup/cpuset.mems
15862306a36Sopenharmony_ci    echo 0 >$CGROUP_ROOT/$cgroup/cpuset.cpus
15962306a36Sopenharmony_ci    echo $$ >"$CGROUP_ROOT/$cgroup/tasks"
16062306a36Sopenharmony_ci  fi
16162306a36Sopenharmony_ci  ./write_to_hugetlbfs -p "$path" -s "$size" -m 0 -o
16262306a36Sopenharmony_ci  if [[ $cgroup2 ]]; then
16362306a36Sopenharmony_ci    echo $$ >$CGROUP_ROOT/cgroup.procs
16462306a36Sopenharmony_ci  else
16562306a36Sopenharmony_ci    echo $$ >"$CGROUP_ROOT/tasks"
16662306a36Sopenharmony_ci  fi
16762306a36Sopenharmony_ci  echo
16862306a36Sopenharmony_ci}
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ciset -e
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cisize=$((${MB} * 1024 * 1024 * 25)) # 50MB = 25 * 2MB hugepages.
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cicleanup
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ciecho
17762306a36Sopenharmony_ciecho
17862306a36Sopenharmony_ciecho Test charge, rmdir, uncharge
17962306a36Sopenharmony_cisetup
18062306a36Sopenharmony_ciecho mkdir
18162306a36Sopenharmony_cimkdir $CGROUP_ROOT/test1
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ciecho write
18462306a36Sopenharmony_ciwrite_hugetlbfs test1 "$MNT"/test $size
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ciecho rmdir
18762306a36Sopenharmony_cirmdir $CGROUP_ROOT/test1
18862306a36Sopenharmony_cimkdir $CGROUP_ROOT/test1
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciecho uncharge
19162306a36Sopenharmony_cirm -rf /mnt/huge/*
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cicleanup
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ciecho done
19662306a36Sopenharmony_ciecho
19762306a36Sopenharmony_ciecho
19862306a36Sopenharmony_ciif [[ ! $cgroup2 ]]; then
19962306a36Sopenharmony_ci  echo "Test parent and child hugetlb usage"
20062306a36Sopenharmony_ci  setup
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci  echo write
20362306a36Sopenharmony_ci  write_hugetlbfs a "$MNT"/test $size
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci  echo Assert memory charged correctly for parent use.
20662306a36Sopenharmony_ci  assert_state 0 $size 0 0
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci  write_hugetlbfs a/b "$MNT"/test2 $size
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci  echo Assert memory charged correctly for child use.
21162306a36Sopenharmony_ci  assert_state 0 $(($size * 2)) 0 $size
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci  rmdir "$CGROUP_ROOT"/a/b
21462306a36Sopenharmony_ci  sleep 5
21562306a36Sopenharmony_ci  echo Assert memory reparent correctly.
21662306a36Sopenharmony_ci  assert_state 0 $(($size * 2))
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci  rm -rf "$MNT"/*
21962306a36Sopenharmony_ci  umount "$MNT"
22062306a36Sopenharmony_ci  echo Assert memory uncharged correctly.
22162306a36Sopenharmony_ci  assert_state 0 0
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci  cleanup
22462306a36Sopenharmony_cifi
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ciecho
22762306a36Sopenharmony_ciecho
22862306a36Sopenharmony_ciecho "Test child only hugetlb usage"
22962306a36Sopenharmony_ciecho setup
23062306a36Sopenharmony_cisetup
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ciecho write
23362306a36Sopenharmony_ciwrite_hugetlbfs a/b "$MNT"/test2 $size
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ciecho Assert memory charged correctly for child only use.
23662306a36Sopenharmony_ciassert_state 0 $(($size)) 0 $size
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_cirmdir "$CGROUP_ROOT"/a/b
23962306a36Sopenharmony_ciecho Assert memory reparent correctly.
24062306a36Sopenharmony_ciassert_state 0 $size
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_cirm -rf "$MNT"/*
24362306a36Sopenharmony_ciumount "$MNT"
24462306a36Sopenharmony_ciecho Assert memory uncharged correctly.
24562306a36Sopenharmony_ciassert_state 0 0
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_cicleanup
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ciecho ALL PASS
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ciumount $CGROUP_ROOT
25262306a36Sopenharmony_cirm -rf $CGROUP_ROOT
253