selftest/cgroup: Clean up and restructure test_cpuset_prs.sh

Cleaning up the test_cpuset_prs.sh script and restructure some of the
functions so that a new test matrix with a different cgroup directory
structure can be added in the next patch.

Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
pull/1191/merge
Waiman Long 2025-03-30 17:52:47 -04:00 committed by Tejun Heo
parent 65046b5e0a
commit b2b2b4d058
1 changed files with 156 additions and 101 deletions

View File

@ -88,22 +88,30 @@ echo "" > test/cpuset.cpus
# If isolated CPUs have been reserved at boot time (as shown in
# cpuset.cpus.isolated), these isolated CPUs should be outside of CPUs 0-8
# that will be used by this script for testing purpose. If not, some of
# the tests may fail incorrectly. These pre-isolated CPUs should stay in
# an isolated state throughout the testing process for now.
# the tests may fail incorrectly. Wait a bit and retry again just in case
# these isolated CPUs are leftover from previous run and have just been
# cleaned up earlier in this script.
#
# These pre-isolated CPUs should stay in an isolated state throughout the
# testing process for now.
#
BOOT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
[[ -n "$BOOT_ISOLCPUS" ]] && {
sleep 0.5
BOOT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
}
if [[ -n "$BOOT_ISOLCPUS" ]]
then
[[ $(echo $BOOT_ISOLCPUS | sed -e "s/[,-].*//") -le 8 ]] &&
skip_test "Pre-isolated CPUs ($BOOT_ISOLCPUS) overlap CPUs to be tested"
echo "Pre-isolated CPUs: $BOOT_ISOLCPUS"
fi
cleanup()
{
online_cpus
cd $CGROUP2
rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1
rmdir test > /dev/null 2>&1
rmdir A1/A2/A3 A1/A2 A1 B1 test/A1 test/B1 test > /dev/null 2>&1
[[ -n "$SCHED_DEBUG" ]] &&
echo "$SCHED_DEBUG" > /sys/kernel/debug/sched/verbose
}
@ -173,14 +181,22 @@ test_add_proc()
#
# Cgroup test hierarchy
#
# root -- A1 -- A2 -- A3
# +- B1
# root
# |
# +------+------+
# | |
# A1 B1
# |
# A2
# |
# A3
#
# P<v> = set cpus.partition (0:member, 1:root, 2:isolated)
# C<l> = add cpu-list to cpuset.cpus
# X<l> = add cpu-list to cpuset.cpus.exclusive
# S<p> = use prefix in subtree_control
# T = put a task into cgroup
# CX<l> = add cpu-list to both cpuset.cpus and cpuset.cpus.exclusive
# O<c>=<v> = Write <v> to CPU online file of <c>
#
# ECPUs - effective CPUs of cpusets
@ -453,25 +469,26 @@ set_ctrl_state()
PFILE=$CGRP/cpuset.cpus.partition
CFILE=$CGRP/cpuset.cpus
XFILE=$CGRP/cpuset.cpus.exclusive
S=$(expr substr $CMD 1 1)
if [[ $S = S ]]
then
PREFIX=${CMD#?}
case $CMD in
S*) PREFIX=${CMD#?}
COMM="echo ${PREFIX}${CTRL} > $SFILE"
eval $COMM $REDIRECT
elif [[ $S = X ]]
then
;;
X*)
CPUS=${CMD#?}
COMM="echo $CPUS > $XFILE"
eval $COMM $REDIRECT
elif [[ $S = C ]]
then
CPUS=${CMD#?}
;;
CX*)
CPUS=${CMD#??}
COMM="echo $CPUS > $CFILE; echo $CPUS > $XFILE"
eval $COMM $REDIRECT
;;
C*) CPUS=${CMD#?}
COMM="echo $CPUS > $CFILE"
eval $COMM $REDIRECT
elif [[ $S = P ]]
then
VAL=${CMD#?}
;;
P*) VAL=${CMD#?}
case $VAL in
0) VAL=member
;;
@ -486,15 +503,17 @@ set_ctrl_state()
esac
COMM="echo $VAL > $PFILE"
eval $COMM $REDIRECT
elif [[ $S = O ]]
then
VAL=${CMD#?}
;;
O*) VAL=${CMD#?}
write_cpu_online $VAL
elif [[ $S = T ]]
then
COMM="echo 0 > $TFILE"
;;
T*) COMM="echo 0 > $TFILE"
eval $COMM $REDIRECT
fi
;;
*) echo "Unknown command: $CMD"
exit 1
;;
esac
RET=$?
[[ $RET -ne 0 ]] && {
[[ -n "$SHOWERR" ]] && {
@ -532,21 +551,18 @@ online_cpus()
}
#
# Return 1 if the list of effective cpus isn't the same as the initial list.
# Remove all the test cgroup directories
#
reset_cgroup_states()
{
echo 0 > $CGROUP2/cgroup.procs
online_cpus
rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1
pause 0.02
set_ctrl_state . R-
pause 0.01
rmdir $RESET_LIST > /dev/null 2>&1
}
dump_states()
{
for DIR in . A1 A1/A2 A1/A2/A3 B1
for DIR in $CGROUP_LIST
do
CPUS=$DIR/cpuset.cpus
ECPUS=$DIR/cpuset.cpus.effective
@ -565,6 +581,21 @@ dump_states()
done
}
#
# Set the actual cgroup directory into $CGRP_DIR
# $1 - cgroup name
#
set_cgroup_dir()
{
CGRP_DIR=$1
[[ $CGRP_DIR = A2 ]] && CGRP_DIR=A1/A2
[[ $CGRP_DIR = A3 ]] && CGRP_DIR=A1/A2/A3
[[ $CGRP_DIR = c11 ]] && CGRP_DIR=p1/c11
[[ $CGRP_DIR = c12 ]] && CGRP_DIR=p1/c12
[[ $CGRP_DIR = c21 ]] && CGRP_DIR=p2/c21
[[ $CGRP_DIR = c22 ]] && CGRP_DIR=p2/c22
}
#
# Check effective cpus
# $1 - check string, format: <cgroup>:<cpu-list>[|<cgroup>:<cpu-list>]*
@ -576,7 +607,8 @@ check_effective_cpus()
do
set -- $(echo $CHK | sed -e "s/:/ /g")
CGRP=$1
CPUS=$2
EXPECTED_CPUS=$2
ACTUAL_CPUS=
if [[ $CGRP = X* ]]
then
CGRP=${CGRP#X}
@ -584,10 +616,10 @@ check_effective_cpus()
else
FILE=cpuset.cpus.effective
fi
[[ $CGRP = A2 ]] && CGRP=A1/A2
[[ $CGRP = A3 ]] && CGRP=A1/A2/A3
[[ -e $CGRP/$FILE ]] || return 1
[[ $CPUS = $(cat $CGRP/$FILE) ]] || return 1
set_cgroup_dir $CGRP
[[ -e $CGRP_DIR/$FILE ]] || return 1
ACTUAL_CPUS=$(cat $CGRP_DIR/$FILE)
[[ $EXPECTED_CPUS = $ACTUAL_CPUS ]] || return 1
done
}
@ -602,23 +634,21 @@ check_cgroup_states()
do
set -- $(echo $CHK | sed -e "s/:/ /g")
CGRP=$1
CGRP_DIR=$CGRP
STATE=$2
EXPECTED_STATE=$2
FILE=
EVAL=$(expr substr $STATE 2 2)
[[ $CGRP = A2 ]] && CGRP_DIR=A1/A2
[[ $CGRP = A3 ]] && CGRP_DIR=A1/A2/A3
EVAL=$(expr substr $EXPECTED_STATE 2 2)
case $STATE in
set_cgroup_dir $CGRP
case $EXPECTED_STATE in
P*) FILE=$CGRP_DIR/cpuset.cpus.partition
;;
*) echo "Unknown state: $STATE!"
*) echo "Unknown state: $EXPECTED_STATE!"
exit 1
;;
esac
VAL=$(cat $FILE)
ACTUAL_STATE=$(cat $FILE)
case "$VAL" in
case "$ACTUAL_STATE" in
member) VAL=0
;;
root) VAL=1
@ -642,7 +672,7 @@ check_cgroup_states()
[[ $VAL -eq 1 && $VERBOSE -gt 0 ]] && {
DOMS=$(cat $CGRP_DIR/cpuset.cpus.effective)
[[ -n "$DOMS" ]] &&
echo " [$CGRP] sched-domain: $DOMS" > $CONSOLE
echo " [$CGRP_DIR] sched-domain: $DOMS" > $CONSOLE
}
done
return 0
@ -665,22 +695,22 @@ check_cgroup_states()
#
check_isolcpus()
{
EXPECT_VAL=$1
ISOLCPUS=
EXPECTED_ISOLCPUS=$1
ISCPUS=${CGROUP2}/cpuset.cpus.isolated
ISOLCPUS=$(cat $ISCPUS)
LASTISOLCPU=
SCHED_DOMAINS=/sys/kernel/debug/sched/domains
ISCPUS=${CGROUP2}/cpuset.cpus.isolated
if [[ $EXPECT_VAL = . ]]
if [[ $EXPECTED_ISOLCPUS = . ]]
then
EXPECT_VAL=
EXPECT_VAL2=
elif [[ $(expr $EXPECT_VAL : ".*|.*") > 0 ]]
EXPECTED_ISOLCPUS=
EXPECTED_SDOMAIN=
elif [[ $(expr $EXPECTED_ISOLCPUS : ".*|.*") > 0 ]]
then
set -- $(echo $EXPECT_VAL | sed -e "s/|/ /g")
EXPECT_VAL=$1
EXPECT_VAL2=$2
set -- $(echo $EXPECTED_ISOLCPUS | sed -e "s/|/ /g")
EXPECTED_ISOLCPUS=$2
EXPECTED_SDOMAIN=$1
else
EXPECT_VAL2=$EXPECT_VAL
EXPECTED_SDOMAIN=$EXPECTED_ISOLCPUS
fi
#
@ -689,20 +719,21 @@ check_isolcpus()
# to make appending those CPUs easier.
#
[[ -n "$BOOT_ISOLCPUS" ]] && {
EXPECT_VAL=${EXPECT_VAL:+${EXPECT_VAL},}${BOOT_ISOLCPUS}
EXPECT_VAL2=${EXPECT_VAL2:+${EXPECT_VAL2},}${BOOT_ISOLCPUS}
EXPECTED_ISOLCPUS=${EXPECTED_ISOLCPUS:+${EXPECTED_ISOLCPUS},}${BOOT_ISOLCPUS}
EXPECTED_SDOMAIN=${EXPECTED_SDOMAIN:+${EXPECTED_SDOMAIN},}${BOOT_ISOLCPUS}
}
#
# Check cpuset.cpus.isolated cpumask
#
[[ "$EXPECT_VAL2" != "$ISOLCPUS" ]] && {
[[ "$EXPECTED_ISOLCPUS" != "$ISOLCPUS" ]] && {
# Take a 50ms pause and try again
pause 0.05
ISOLCPUS=$(cat $ISCPUS)
}
[[ "$EXPECT_VAL2" != "$ISOLCPUS" ]] && return 1
[[ "$EXPECTED_ISOLCPUS" != "$ISOLCPUS" ]] && return 1
ISOLCPUS=
EXPECTED_ISOLCPUS=$EXPECTED_SDOMAIN
#
# Use the sched domain in debugfs to check isolated CPUs, if available
@ -736,7 +767,7 @@ check_isolcpus()
done
[[ "$ISOLCPUS" = *- ]] && ISOLCPUS=${ISOLCPUS}$LASTISOLCPU
[[ "$EXPECT_VAL" = "$ISOLCPUS" ]]
[[ "$EXPECTED_SDOMAIN" = "$ISOLCPUS" ]]
}
test_fail()
@ -773,6 +804,63 @@ null_isolcpus_check()
exit 1
}
#
# Check state transition test result
# $1 - Test number
# $2 - Expected effective CPU values
# $3 - Expected partition states
# $4 - Expected isolated CPUs
#
check_test_results()
{
_NR=$1
_ECPUS="$2"
_PSTATES="$3"
_ISOLCPUS="$4"
[[ -n "$_ECPUS" && "$_ECPUS" != . ]] && {
check_effective_cpus $_ECPUS
[[ $? -ne 0 ]] && test_fail $_NR "effective CPU" \
"Cgroup $CGRP: expected $EXPECTED_CPUS, got $ACTUAL_CPUS"
}
[[ -n "$_PSTATES" && "$_PSTATES" != . ]] && {
check_cgroup_states $_PSTATES
[[ $? -ne 0 ]] && test_fail $_NR states \
"Cgroup $CGRP: expected $EXPECTED_STATE, got $ACTUAL_STATE"
}
# Compare the expected isolated CPUs with the actual ones,
# if available
[[ -n "$_ISOLCPUS" ]] && {
check_isolcpus $_ISOLCPUS
[[ $? -ne 0 ]] && {
[[ -n "$BOOT_ISOLCPUS" ]] && _ISOLCPUS=${_ISOLCPUS},${BOOT_ISOLCPUS}
test_fail $_NR "isolated CPU" \
"Expect $_ISOLCPUS, get $ISOLCPUS instead"
}
}
reset_cgroup_states
#
# Check to see if effective cpu list changes
#
_NEWLIST=$(cat $CGROUP2/cpuset.cpus.effective)
RETRY=0
while [[ $_NEWLIST != $CPULIST && $RETRY -lt 8 ]]
do
# Wait a bit longer & recheck a few times
pause 0.02
((RETRY++))
_NEWLIST=$(cat $CGROUP2/cpuset.cpus.effective)
done
[[ $_NEWLIST != $CPULIST ]] && {
echo "Effective cpus changed to $_NEWLIST after test $_NR!"
exit 1
}
null_isolcpus_check
[[ $VERBOSE -gt 0 ]] && echo "Test $I done."
}
#
# Run cpuset state transition test
# $1 - test matrix name
@ -785,6 +873,8 @@ run_state_test()
{
TEST=$1
CONTROLLER=cpuset
CGROUP_LIST=". A1 A1/A2 A1/A2/A3 B1"
RESET_LIST="A1/A2/A3 A1/A2 A1 B1"
I=0
eval CNT="\${#$TEST[@]}"
@ -824,45 +914,7 @@ run_state_test()
[[ $RETVAL -ne $RESULT ]] && test_fail $I result
[[ -n "$ECPUS" && "$ECPUS" != . ]] && {
check_effective_cpus $ECPUS
[[ $? -ne 0 ]] && test_fail $I "effective CPU"
}
[[ -n "$STATES" && "$STATES" != . ]] && {
check_cgroup_states $STATES
[[ $? -ne 0 ]] && test_fail $I states
}
# Compare the expected isolated CPUs with the actual ones,
# if available
[[ -n "$ICPUS" ]] && {
check_isolcpus $ICPUS
[[ $? -ne 0 ]] && {
[[ -n "$BOOT_ISOLCPUS" ]] && ICPUS=${ICPUS},${BOOT_ISOLCPUS}
test_fail $I "isolated CPU" \
"Expect $ICPUS, get $ISOLCPUS instead"
}
}
reset_cgroup_states
#
# Check to see if effective cpu list changes
#
NEWLIST=$(cat cpuset.cpus.effective)
RETRY=0
while [[ $NEWLIST != $CPULIST && $RETRY -lt 8 ]]
do
# Wait a bit longer & recheck a few times
pause 0.02
((RETRY++))
NEWLIST=$(cat cpuset.cpus.effective)
done
[[ $NEWLIST != $CPULIST ]] && {
echo "Effective cpus changed to $NEWLIST after test $I!"
exit 1
}
null_isolcpus_check
[[ $VERBOSE -gt 0 ]] && echo "Test $I done."
check_test_results $I "$ECPUS" "$STATES" "$ICPUS"
((I++))
done
echo "All $I tests of $TEST PASSED."
@ -932,6 +984,7 @@ test_isolated()
echo $$ > $CGROUP2/cgroup.procs
[[ -d A1 ]] && rmdir A1
null_isolcpus_check
pause 0.05
}
#
@ -997,6 +1050,8 @@ test_inotify()
else
echo "Inotify test PASSED"
fi
echo member > cpuset.cpus.partition
echo "" > cpuset.cpus
}
trap cleanup 0 2 3 6