Whenever a partition is enabled or the cpumask of a valid partition
changes, a housekeeping check will be performed to ensure that the
change won't violate the imposed housekeeping constraints. One of the
constraints is that a boot-time isolated CPU will not be used to form
a non-isolated root partition. This requires the presence of boot-time
isolated CPUs when a test is run.

The test_cpuset_prs.sh test script is now updated to run a set a
special housekeeping check tests that will only be run if a suitable
boot-time isolated CPU is present. This will enable us to detect bugs
or regressions in the housekeeping checking code though a "isolcpus="
boot parameter with CPUs beyond CPU 8 must be present.

This patch also includes a minor fix to the REMOTE_TEST_MATRIX to avoid
test failure when the -v option is used.

Signed-off-by: Waiman Long <[email protected]>
---
 .../selftests/cgroup/test_cpuset_prs.sh       | 120 ++++++++++++++----
 1 file changed, 98 insertions(+), 22 deletions(-)

diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh 
b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
index 85a4f87840b4..5aac0df86593 100755
--- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh
+++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
@@ -86,26 +86,37 @@ 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. 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.
+# /sys/devices/system/cpu/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
+# The current set of isolated CPUs (as shown in cpuset.cpus.isolated) should
+# be the same as the boot value. If not, 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. If they still don't match, we report an
+# warning and skip the test.
+#
+# These boot isolated CPUs should stay in an isolated state throughout the
 # testing process for now.
 #
-BOOT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
+BOOT_ISOLCPUS=$(cat /sys/devices/system/cpu/isolated)
+CURRENT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
+FIRST_ISOLCPUS=
+TEST_ISOLCPUS=
+
 [[ -n "$BOOT_ISOLCPUS" ]] && {
+       FIRST_ISOLCPUS=$(echo $BOOT_ISOLCPUS | sed -e "s/[,-].*//")
+       echo "Boot isolated CPUs: $BOOT_ISOLCPUS"
+       [[ $FIRST_ISOLCPUS -le 8 ]] &&
+               skip_test "Boot isolated CPUs overlap CPUs to be tested"
+}
+
+[[ "$BOOT_ISOLCPUS" != "$CURRENT_ISOLCPUS" ]] && {
        sleep 0.5
-       BOOT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
+       CURRENT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
+       [[ "$BOOT_ISOLCPUS" != "$CURRENT_ISOLCPUS" ]] &&
+               skip_test "Current isolated CPUs ($CURRENT_ISOLCPUS) don't 
match boot isolated CPUs!"
 }
-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()
 {
@@ -202,7 +213,7 @@ test_add_proc()
 #
 # ECPUs    - effective CPUs of cpusets
 # Pstate   - partition root state
-# ISOLCPUS - isolated CPUs (<icpus>[,<icpus2>])
+# ISOLCPUS - isolated CPUs (<icpus>[,<icpus2>] or .)
 #
 # Note that if there are 2 fields in ISOLCPUS, the first one is for
 # sched-debug matching which includes offline CPUs and single-CPU partitions
@@ -446,6 +457,46 @@ TEST_MATRIX=(
        "   C0-3     .      .    C4-5   X3-5     .      .      .     1 
A1:0-3|B1:4-5"
 )
 
+# Test matrix with boot time isolated CPUs present for housekeeping check 
testing
+ISOLCPUS_TEST_MATRIX=(
+       #  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs 
Pstate ISOLCPUS
+       #  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- 
------ --------
+       # A local isolated partition containing boot isolated CPU cannot be
+       # switched to root partition.
+       " C1-2,I:P2  .      .      .      P1     .      .      .     0 A1:1-2,I 
A1:P-1 ."
+
+       # A remote isolated partition containing boot isolated CPU cannot be
+       # switched to root partition.
+       " X1-2,I CX1-2,I:P2 .      .       .    P1      .      .     0 A2:1-2,I 
A2:P-1 ."
+
+       # A local isolated partition with a boot isolated CPU distributed to a
+       # child isolated partition also cannot be switched to a root partition.
+       " C1-3,I:P2 C1,I:P2 .      .      P1     .      .      .     0 
A1:1-3,I|A2:1,I A1:P-1|A2:P-2 ."
+
+       # A remote isolated partition with a boot isolated CPU distributed to a
+       # child isolated partition also cannot be switched to a root partition.
+       " X1-3,I C1-3,I:P2 C1,I:P2 .       .    P1      .      .     0 
A2:1-3,I|A3:1,I A2:P-1|A3:P-2 ."
+
+       # The cpumask of a local root partition cannot be changed to include a
+       # boot isolated CPU.
+       " C1-2:P1    .      .      .     C2,I    .      .      .     0 A1:2,I 
A1:P-1 ."
+
+       # The cpumask of a remote root partition cannot be changed to include a
+       # boot isolated CPU.
+       " CX1-2,I  CX1-2:P1 .      .       .   CX2,I    .      .     0 
A1:1-2,I|A2:2,I A2:P-1 ."
+
+       # Passing an boot isolated CPU down to a child root partition will 
invalidate it
+       " C2-3,I:X2-3 CX2-3,I .    .       .    P1      .      .     0 
A1:I|A2:2-3 A2:P1 ."
+       " C2-3,I:X2-3 CX2-3,I:P1 . .     X2-3,I  .      .      .     0 
A1:2-3,I|A2:2-3,I A2:P-1 ."
+
+       # An invalidated root partition must stay invalid when cpus grows but
+       # effective xcpus still contains a boot isolated CPU.
+       " CX1,I:P1   .      .      .     C1,2,I  .      .      .     0 
A1:1-2,I|XA1:1,I A1:P-1 ."
+
+       # Growing cpus.exclusive must not revive it either
+       " CX1-2,I:X1,I:P1 . .      .     X1,2,I  .      .      .     0 
A1:1-2,I|XA1:1-2,I A1:P-1 ."
+)
+
 #
 # Cpuset controller remote partition test matrix.
 #
@@ -498,8 +549,8 @@ REMOTE_TEST_MATRIX=(
                                                         p1:P1|c11:P1|c12:P-1"
        # Narrowing cpuset.cpus to previously sibling-excluded CPUs should
        # not return CPUs that were never actually owned.
-       "  C1-4:P1   .   C1-2:P1  C1-3:P2  .       .  \
-             .      .     .       C3      .       .     p1:4|c11:1-2|c12:3 \
+       "  C1-5:P1   .   C1-2:P1  C1-3:P2  .       .  \
+             .      .     .       C3      .       .     p1:4-5|c11:1-2|c12:3 \
                                                         p1:P1|c11:P1|c12:P2 3"
        # Expanding cpuset.cpus to include a previously sibling-excluded CPU
        # after the sibling has become a member should correctly request it.
@@ -543,6 +594,27 @@ write_cpu_online()
        pause 0.05
 }
 
+#
+# Set the CPUS variable
+#  $1 - the passed in cpu parameter
+#
+# The special "I" CPU if present is being replaced by the first boot CPU
+# and assigned to the "CPUS" variable when the TEST_ISOLCPUS flag is set.
+# If not, the program will exit with an error.
+#
+set_cpus()
+{
+       local cpus=$1
+       if [[ $(expr "$cpus" : ".*I") -gt 0 ]]
+       then
+               [[ -z "$TEST_ISOLCPUS" ]] &&
+                       skip_test "Special 'I' CPU added to non-isolcpus 
testing matrix!"
+               CPUS=$(echo $cpus | sed -e "s/I/$FIRST_ISOLCPUS/")
+       else
+               CPUS=$cpus
+       fi
+}
+
 #
 # Set controller state
 #  $1 - cgroup directory
@@ -577,16 +649,16 @@ set_ctrl_state()
                }
                case $CMD in
                    X*)
-                       CPUS=${CMD#?}
+                       set_cpus ${CMD#?}
                        COMM="echo $CPUS > $XFILE"
                        eval $COMM $REDIRECT
                        ;;
                    CX*)
-                       CPUS=${CMD#??}
+                       set_cpus ${CMD#??}
                        COMM="echo $CPUS > $CFILE; echo $CPUS > $XFILE"
                        eval $COMM $REDIRECT
                        ;;
-                   C*) CPUS=${CMD#?}
+                   C*) set_cpus ${CMD#?}
                        COMM="echo $CPUS > $CFILE"
                        eval $COMM $REDIRECT
                        ;;
@@ -980,8 +1052,11 @@ run_state_test()
        I=0
        eval CNT="\${#$TEST[@]}"
 
+       # Skip isolcpus specific test matrix if FIRST_ISOLCPUS not defined
+       [[ -n "$TEST_ISOLCPUS" && -z "$FIRST_ISOLCPUS" ]] && return
+
        reset_cgroup_states
-       console_msg "Running state transition test ..."
+       console_msg "Running state transition test for $TEST ..."
 
        while [[ $I -lt $CNT ]]
        do
@@ -1000,7 +1075,7 @@ run_state_test()
                NEW_A3=$7
                NEW_B1=$8
                RESULT=$9
-               ECPUS=${10}
+               ECPUS=$(echo ${10} | sed -e "s/I/${FIRST_ISOLCPUS}/g")
                STATES=${11}
                ICPUS=${12}
 
@@ -1286,6 +1361,7 @@ test_inotify()
 trap cleanup 0 2 3 6
 run_state_test TEST_MATRIX
 run_remote_state_test REMOTE_TEST_MATRIX
+TEST_ISOLCPUS=1 run_state_test ISOLCPUS_TEST_MATRIX
 test_isolated
 test_boot_isolated
 test_inotify
-- 
2.55.0


Reply via email to