linux/tools/testing/selftests/vm/hugetlb_reparenting_test.sh
Po-Hsu Lin 6260618e09 selftests/vm: use kselftest skip code for skipped tests
There are several test cases in the vm directory are still using exit 0
when they need to be skipped.  Use the kselftest framework to skip code
instead so it can help us to distinguish the return status.

Criterion to filter out what should be fixed in vm directory:
  grep -r "exit 0" -B1 | grep -i skip

This change might cause some false-positives if people are running these
test scripts directly and only checking their return codes, which will
change from 0 to 4.  However I think the impact should be small as most of
our scripts here are already using this skip code.  And there will be no
such issue if running them with the kselftest framework.

Link: https://lkml.kernel.org/r/20210823073433.37653-1-po-hsu.lin@canonical.com
Signed-off-by: Po-Hsu Lin <po-hsu.lin@canonical.com>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-09-03 09:58:13 -07:00

248 lines
5.2 KiB
Bash

#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
set -e
if [[ $(id -u) -ne 0 ]]; then
echo "This test must be run as root. Skipping..."
exit $ksft_skip
fi
usage_file=usage_in_bytes
if [[ "$1" == "-cgroup-v2" ]]; then
cgroup2=1
usage_file=current
fi
CGROUP_ROOT='/dev/cgroup/memory'
MNT='/mnt/huge/'
if [[ ! -e $CGROUP_ROOT ]]; then
mkdir -p $CGROUP_ROOT
if [[ $cgroup2 ]]; then
mount -t cgroup2 none $CGROUP_ROOT
sleep 1
echo "+hugetlb +memory" >$CGROUP_ROOT/cgroup.subtree_control
else
mount -t cgroup memory,hugetlb $CGROUP_ROOT
fi
fi
function get_machine_hugepage_size() {
hpz=$(grep -i hugepagesize /proc/meminfo)
kb=${hpz:14:-3}
mb=$(($kb / 1024))
echo $mb
}
MB=$(get_machine_hugepage_size)
function cleanup() {
echo cleanup
set +e
rm -rf "$MNT"/* 2>/dev/null
umount "$MNT" 2>/dev/null
rmdir "$MNT" 2>/dev/null
rmdir "$CGROUP_ROOT"/a/b 2>/dev/null
rmdir "$CGROUP_ROOT"/a 2>/dev/null
rmdir "$CGROUP_ROOT"/test1 2>/dev/null
echo 0 >/proc/sys/vm/nr_hugepages
set -e
}
function assert_state() {
local expected_a="$1"
local expected_a_hugetlb="$2"
local expected_b=""
local expected_b_hugetlb=""
if [ ! -z ${3:-} ] && [ ! -z ${4:-} ]; then
expected_b="$3"
expected_b_hugetlb="$4"
fi
local tolerance=$((5 * 1024 * 1024))
local actual_a
actual_a="$(cat "$CGROUP_ROOT"/a/memory.$usage_file)"
if [[ $actual_a -lt $(($expected_a - $tolerance)) ]] ||
[[ $actual_a -gt $(($expected_a + $tolerance)) ]]; then
echo actual a = $((${actual_a%% *} / 1024 / 1024)) MB
echo expected a = $((${expected_a%% *} / 1024 / 1024)) MB
echo fail
cleanup
exit 1
fi
local actual_a_hugetlb
actual_a_hugetlb="$(cat "$CGROUP_ROOT"/a/hugetlb.${MB}MB.$usage_file)"
if [[ $actual_a_hugetlb -lt $(($expected_a_hugetlb - $tolerance)) ]] ||
[[ $actual_a_hugetlb -gt $(($expected_a_hugetlb + $tolerance)) ]]; then
echo actual a hugetlb = $((${actual_a_hugetlb%% *} / 1024 / 1024)) MB
echo expected a hugetlb = $((${expected_a_hugetlb%% *} / 1024 / 1024)) MB
echo fail
cleanup
exit 1
fi
if [[ -z "$expected_b" || -z "$expected_b_hugetlb" ]]; then
return
fi
local actual_b
actual_b="$(cat "$CGROUP_ROOT"/a/b/memory.$usage_file)"
if [[ $actual_b -lt $(($expected_b - $tolerance)) ]] ||
[[ $actual_b -gt $(($expected_b + $tolerance)) ]]; then
echo actual b = $((${actual_b%% *} / 1024 / 1024)) MB
echo expected b = $((${expected_b%% *} / 1024 / 1024)) MB
echo fail
cleanup
exit 1
fi
local actual_b_hugetlb
actual_b_hugetlb="$(cat "$CGROUP_ROOT"/a/b/hugetlb.${MB}MB.$usage_file)"
if [[ $actual_b_hugetlb -lt $(($expected_b_hugetlb - $tolerance)) ]] ||
[[ $actual_b_hugetlb -gt $(($expected_b_hugetlb + $tolerance)) ]]; then
echo actual b hugetlb = $((${actual_b_hugetlb%% *} / 1024 / 1024)) MB
echo expected b hugetlb = $((${expected_b_hugetlb%% *} / 1024 / 1024)) MB
echo fail
cleanup
exit 1
fi
}
function setup() {
echo 100 >/proc/sys/vm/nr_hugepages
mkdir "$CGROUP_ROOT"/a
sleep 1
if [[ $cgroup2 ]]; then
echo "+hugetlb +memory" >$CGROUP_ROOT/a/cgroup.subtree_control
else
echo 0 >$CGROUP_ROOT/a/cpuset.mems
echo 0 >$CGROUP_ROOT/a/cpuset.cpus
fi
mkdir "$CGROUP_ROOT"/a/b
if [[ ! $cgroup2 ]]; then
echo 0 >$CGROUP_ROOT/a/b/cpuset.mems
echo 0 >$CGROUP_ROOT/a/b/cpuset.cpus
fi
mkdir -p "$MNT"
mount -t hugetlbfs none "$MNT"
}
write_hugetlbfs() {
local cgroup="$1"
local path="$2"
local size="$3"
if [[ $cgroup2 ]]; then
echo $$ >$CGROUP_ROOT/$cgroup/cgroup.procs
else
echo 0 >$CGROUP_ROOT/$cgroup/cpuset.mems
echo 0 >$CGROUP_ROOT/$cgroup/cpuset.cpus
echo $$ >"$CGROUP_ROOT/$cgroup/tasks"
fi
./write_to_hugetlbfs -p "$path" -s "$size" -m 0 -o
if [[ $cgroup2 ]]; then
echo $$ >$CGROUP_ROOT/cgroup.procs
else
echo $$ >"$CGROUP_ROOT/tasks"
fi
echo
}
set -e
size=$((${MB} * 1024 * 1024 * 25)) # 50MB = 25 * 2MB hugepages.
cleanup
echo
echo
echo Test charge, rmdir, uncharge
setup
echo mkdir
mkdir $CGROUP_ROOT/test1
echo write
write_hugetlbfs test1 "$MNT"/test $size
echo rmdir
rmdir $CGROUP_ROOT/test1
mkdir $CGROUP_ROOT/test1
echo uncharge
rm -rf /mnt/huge/*
cleanup
echo done
echo
echo
if [[ ! $cgroup2 ]]; then
echo "Test parent and child hugetlb usage"
setup
echo write
write_hugetlbfs a "$MNT"/test $size
echo Assert memory charged correctly for parent use.
assert_state 0 $size 0 0
write_hugetlbfs a/b "$MNT"/test2 $size
echo Assert memory charged correctly for child use.
assert_state 0 $(($size * 2)) 0 $size
rmdir "$CGROUP_ROOT"/a/b
sleep 5
echo Assert memory reparent correctly.
assert_state 0 $(($size * 2))
rm -rf "$MNT"/*
umount "$MNT"
echo Assert memory uncharged correctly.
assert_state 0 0
cleanup
fi
echo
echo
echo "Test child only hugetlb usage"
echo setup
setup
echo write
write_hugetlbfs a/b "$MNT"/test2 $size
echo Assert memory charged correctly for child only use.
assert_state 0 $(($size)) 0 $size
rmdir "$CGROUP_ROOT"/a/b
echo Assert memory reparent correctly.
assert_state 0 $size
rm -rf "$MNT"/*
umount "$MNT"
echo Assert memory uncharged correctly.
assert_state 0 0
cleanup
echo ALL PASS
umount $CGROUP_ROOT
rm -rf $CGROUP_ROOT