xref: /linux/tools/testing/selftests/cgroup/test_cpuset_prs.sh (revision 9d3da7827536b8e41e4188185622816a105b46f7)
1a8c52ebaSWaiman Long#!/bin/bash
2a8c52ebaSWaiman Long# SPDX-License-Identifier: GPL-2.0
3a8c52ebaSWaiman Long#
4a8c52ebaSWaiman Long# Test for cpuset v2 partition root state (PRS)
5a8c52ebaSWaiman Long#
6105f3fe9SWaiman Long# The sched verbose flag can be optionally set so that the console log
7a8c52ebaSWaiman Long# can be examined for the correct setting of scheduling domain.
8a8c52ebaSWaiman Long#
9a8c52ebaSWaiman Long
10a8c52ebaSWaiman Longskip_test() {
11a8c52ebaSWaiman Long	echo "$1"
12a8c52ebaSWaiman Long	echo "Test SKIPPED"
1312101424SMichal Koutný	exit 4 # ksft_skip
14a8c52ebaSWaiman Long}
15a8c52ebaSWaiman Long
16a8c52ebaSWaiman Long[[ $(id -u) -eq 0 ]] || skip_test "Test must be run as root!"
17a8c52ebaSWaiman Long
18a8c52ebaSWaiman Long
19a8c52ebaSWaiman Long# Get wait_inotify location
20a8c52ebaSWaiman LongWAIT_INOTIFY=$(cd $(dirname $0); pwd)/wait_inotify
21a8c52ebaSWaiman Long
22a8c52ebaSWaiman Long# Find cgroup v2 mount point
23a8c52ebaSWaiman LongCGROUP2=$(mount -t cgroup2 | head -1 | awk -e '{print $3}')
24a8c52ebaSWaiman Long[[ -n "$CGROUP2" ]] || skip_test "Cgroup v2 mount point not found!"
25105f3fe9SWaiman LongSUBPARTS_CPUS=$CGROUP2/.__DEBUG__.cpuset.cpus.subpartitions
26105f3fe9SWaiman LongCPULIST=$(cat $CGROUP2/cpuset.cpus.effective)
27a8c52ebaSWaiman Long
28105f3fe9SWaiman LongNR_CPUS=$(lscpu | grep "^CPU(s):" | sed -e "s/.*:[[:space:]]*//")
29105f3fe9SWaiman Long[[ $NR_CPUS -lt 8 ]] && skip_test "Test needs at least 8 cpus available!"
30a8c52ebaSWaiman Long
3143ee4014SWaiman Long# Check to see if /dev/console exists and is writable
3243ee4014SWaiman Longif [[ -c /dev/console && -w /dev/console ]]
3343ee4014SWaiman Longthen
3443ee4014SWaiman Long	CONSOLE=/dev/console
3543ee4014SWaiman Longelse
3643ee4014SWaiman Long	CONSOLE=/dev/null
3743ee4014SWaiman Longfi
3843ee4014SWaiman Long
39a8c52ebaSWaiman Long# Set verbose flag and delay factor
40a8c52ebaSWaiman LongPROG=$1
41105f3fe9SWaiman LongVERBOSE=0
42a8c52ebaSWaiman LongDELAY_FACTOR=1
431bf33285SWaiman LongSCHED_DEBUG=
44a8c52ebaSWaiman Longwhile [[ "$1" = -* ]]
45a8c52ebaSWaiman Longdo
46a8c52ebaSWaiman Long	case "$1" in
47105f3fe9SWaiman Long		-v) ((VERBOSE++))
481bf33285SWaiman Long		    # Enable sched/verbose can slow thing down
491bf33285SWaiman Long		    [[ $DELAY_FACTOR -eq 1 ]] &&
501bf33285SWaiman Long			DELAY_FACTOR=2
51a8c52ebaSWaiman Long		    ;;
52a8c52ebaSWaiman Long		-d) DELAY_FACTOR=$2
53a8c52ebaSWaiman Long		    shift
54a8c52ebaSWaiman Long		    ;;
55a8c52ebaSWaiman Long		*)  echo "Usage: $PROG [-v] [-d <delay-factor>"
56a8c52ebaSWaiman Long		    exit
57a8c52ebaSWaiman Long		    ;;
58a8c52ebaSWaiman Long	esac
59a8c52ebaSWaiman Long	shift
60a8c52ebaSWaiman Longdone
61a8c52ebaSWaiman Long
621bf33285SWaiman Long# Set sched verbose flag if available when "-v" option is specified
63105f3fe9SWaiman Longif [[ $VERBOSE -gt 0 && -d /sys/kernel/debug/sched ]]
641bf33285SWaiman Longthen
651bf33285SWaiman Long	# Used to restore the original setting during cleanup
661bf33285SWaiman Long	SCHED_DEBUG=$(cat /sys/kernel/debug/sched/verbose)
671bf33285SWaiman Long	echo Y > /sys/kernel/debug/sched/verbose
681bf33285SWaiman Longfi
691bf33285SWaiman Long
70a8c52ebaSWaiman Longcd $CGROUP2
71a8c52ebaSWaiman Longecho +cpuset > cgroup.subtree_control
72105f3fe9SWaiman Long
73105f3fe9SWaiman Long#
74105f3fe9SWaiman Long# If cpuset has been set up and used in child cgroups, we may not be able to
75105f3fe9SWaiman Long# create partition under root cgroup because of the CPU exclusivity rule.
76105f3fe9SWaiman Long# So we are going to skip the test if this is the case.
77105f3fe9SWaiman Long#
78a8c52ebaSWaiman Long[[ -d test ]] || mkdir test
79105f3fe9SWaiman Longecho 0-6 > test/cpuset.cpus
80105f3fe9SWaiman Longecho root > test/cpuset.cpus.partition
81105f3fe9SWaiman Longcat test/cpuset.cpus.partition | grep -q invalid
82105f3fe9SWaiman LongRESULT=$?
83105f3fe9SWaiman Longecho member > test/cpuset.cpus.partition
84105f3fe9SWaiman Longecho "" > test/cpuset.cpus
85105f3fe9SWaiman Long[[ $RESULT -eq 0 ]] && skip_test "Child cgroups are using cpuset!"
86a8c52ebaSWaiman Long
8743a17fcfSWaiman Long#
8843a17fcfSWaiman Long# If isolated CPUs have been reserved at boot time (as shown in
899b496a8bSWaiman Long# cpuset.cpus.isolated), these isolated CPUs should be outside of CPUs 0-8
9043a17fcfSWaiman Long# that will be used by this script for testing purpose. If not, some of
91b2b2b4d0SWaiman Long# the tests may fail incorrectly. Wait a bit and retry again just in case
92b2b2b4d0SWaiman Long# these isolated CPUs are leftover from previous run and have just been
93b2b2b4d0SWaiman Long# cleaned up earlier in this script.
94b2b2b4d0SWaiman Long#
95b2b2b4d0SWaiman Long# These pre-isolated CPUs should stay in an isolated state throughout the
96b2b2b4d0SWaiman Long# testing process for now.
9743a17fcfSWaiman Long#
9843a17fcfSWaiman LongBOOT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
99b2b2b4d0SWaiman Long[[ -n "$BOOT_ISOLCPUS" ]] && {
100b2b2b4d0SWaiman Long	sleep 0.5
101b2b2b4d0SWaiman Long	BOOT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
102b2b2b4d0SWaiman Long}
10343a17fcfSWaiman Longif [[ -n "$BOOT_ISOLCPUS" ]]
10443a17fcfSWaiman Longthen
1059b496a8bSWaiman Long	[[ $(echo $BOOT_ISOLCPUS | sed -e "s/[,-].*//") -le 8 ]] &&
10643a17fcfSWaiman Long		skip_test "Pre-isolated CPUs ($BOOT_ISOLCPUS) overlap CPUs to be tested"
10743a17fcfSWaiman Long	echo "Pre-isolated CPUs: $BOOT_ISOLCPUS"
10843a17fcfSWaiman Longfi
109b2b2b4d0SWaiman Long
1101e85591dSKamalesh Babulalcleanup()
1111e85591dSKamalesh Babulal{
1121e85591dSKamalesh Babulal	online_cpus
113105f3fe9SWaiman Long	cd $CGROUP2
114b2b2b4d0SWaiman Long	rmdir A1/A2/A3 A1/A2 A1 B1 test/A1 test/B1 test > /dev/null 2>&1
115*e8a457b7SWaiman Long	rmdir rtest/p1/c11 rtest/p1/c12 rtest/p2/c21 \
116*e8a457b7SWaiman Long	      rtest/p2/c22 rtest/p1 rtest/p2 rtest > /dev/null 2>&1
1171bf33285SWaiman Long	[[ -n "$SCHED_DEBUG" ]] &&
1181e85591dSKamalesh Babulal		echo "$SCHED_DEBUG" > /sys/kernel/debug/sched/verbose
1191e85591dSKamalesh Babulal}
1201e85591dSKamalesh Babulal
121a8c52ebaSWaiman Long# Pause in ms
122a8c52ebaSWaiman Longpause()
123a8c52ebaSWaiman Long{
124a8c52ebaSWaiman Long	DELAY=$1
125a8c52ebaSWaiman Long	LOOP=0
126a8c52ebaSWaiman Long	while [[ $LOOP -lt $DELAY_FACTOR ]]
127a8c52ebaSWaiman Long	do
128a8c52ebaSWaiman Long		sleep $DELAY
129a8c52ebaSWaiman Long		((LOOP++))
130a8c52ebaSWaiman Long	done
131a8c52ebaSWaiman Long	return 0
132a8c52ebaSWaiman Long}
133a8c52ebaSWaiman Long
134a8c52ebaSWaiman Longconsole_msg()
135a8c52ebaSWaiman Long{
136a8c52ebaSWaiman Long	MSG=$1
137a8c52ebaSWaiman Long	echo "$MSG"
13843ee4014SWaiman Long	echo "" > $CONSOLE
13943ee4014SWaiman Long	echo "$MSG" > $CONSOLE
140a8c52ebaSWaiman Long	pause 0.01
141a8c52ebaSWaiman Long}
142a8c52ebaSWaiman Long
143a8c52ebaSWaiman Longtest_partition()
144a8c52ebaSWaiman Long{
145a8c52ebaSWaiman Long	EXPECTED_VAL=$1
146a8c52ebaSWaiman Long	echo $EXPECTED_VAL > cpuset.cpus.partition
147a8c52ebaSWaiman Long	[[ $? -eq 0 ]] || exit 1
148a8c52ebaSWaiman Long	ACTUAL_VAL=$(cat cpuset.cpus.partition)
149a8c52ebaSWaiman Long	[[ $ACTUAL_VAL != $EXPECTED_VAL ]] && {
150105f3fe9SWaiman Long		echo "cpuset.cpus.partition: expect $EXPECTED_VAL, found $ACTUAL_VAL"
151a8c52ebaSWaiman Long		echo "Test FAILED"
152a8c52ebaSWaiman Long		exit 1
153a8c52ebaSWaiman Long	}
154a8c52ebaSWaiman Long}
155a8c52ebaSWaiman Long
156a8c52ebaSWaiman Longtest_effective_cpus()
157a8c52ebaSWaiman Long{
158a8c52ebaSWaiman Long	EXPECTED_VAL=$1
159a8c52ebaSWaiman Long	ACTUAL_VAL=$(cat cpuset.cpus.effective)
160a8c52ebaSWaiman Long	[[ "$ACTUAL_VAL" != "$EXPECTED_VAL" ]] && {
161105f3fe9SWaiman Long		echo "cpuset.cpus.effective: expect '$EXPECTED_VAL', found '$ACTUAL_VAL'"
162a8c52ebaSWaiman Long		echo "Test FAILED"
163a8c52ebaSWaiman Long		exit 1
164a8c52ebaSWaiman Long	}
165a8c52ebaSWaiman Long}
166a8c52ebaSWaiman Long
167a8c52ebaSWaiman Long# Adding current process to cgroup.procs as a test
168a8c52ebaSWaiman Longtest_add_proc()
169a8c52ebaSWaiman Long{
170a8c52ebaSWaiman Long	OUTSTR="$1"
171a8c52ebaSWaiman Long	ERRMSG=$((echo $$ > cgroup.procs) |& cat)
172a8c52ebaSWaiman Long	echo $ERRMSG | grep -q "$OUTSTR"
173a8c52ebaSWaiman Long	[[ $? -ne 0 ]] && {
174a8c52ebaSWaiman Long		echo "cgroup.procs: expect '$OUTSTR', got '$ERRMSG'"
175a8c52ebaSWaiman Long		echo "Test FAILED"
176a8c52ebaSWaiman Long		exit 1
177a8c52ebaSWaiman Long	}
178a8c52ebaSWaiman Long	echo $$ > $CGROUP2/cgroup.procs	# Move out the task
179a8c52ebaSWaiman Long}
180a8c52ebaSWaiman Long
181a8c52ebaSWaiman Long#
182a8c52ebaSWaiman Long# Cpuset controller state transition test matrix.
183a8c52ebaSWaiman Long#
184a8c52ebaSWaiman Long# Cgroup test hierarchy
185a8c52ebaSWaiman Long#
186b2b2b4d0SWaiman Long#	      root
187b2b2b4d0SWaiman Long#	        |
188b2b2b4d0SWaiman Long#	 +------+------+
189b2b2b4d0SWaiman Long#	 |             |
190b2b2b4d0SWaiman Long#	 A1            B1
191b2b2b4d0SWaiman Long#	 |
192b2b2b4d0SWaiman Long#	 A2
193b2b2b4d0SWaiman Long#	 |
194b2b2b4d0SWaiman Long#	 A3
195a8c52ebaSWaiman Long#
196105f3fe9SWaiman Long#  P<v> = set cpus.partition (0:member, 1:root, 2:isolated)
19746c521baSWaiman Long#  C<l> = add cpu-list to cpuset.cpus
19846c521baSWaiman Long#  X<l> = add cpu-list to cpuset.cpus.exclusive
199a8c52ebaSWaiman Long#  S<p> = use prefix in subtree_control
200a8c52ebaSWaiman Long#  T    = put a task into cgroup
201b2b2b4d0SWaiman Long#  CX<l> = add cpu-list to both cpuset.cpus and cpuset.cpus.exclusive
202105f3fe9SWaiman Long#  O<c>=<v> = Write <v> to CPU online file of <c>
203a8c52ebaSWaiman Long#
2041c0be3f7SWaiman Long# ECPUs    - effective CPUs of cpusets
2051c0be3f7SWaiman Long# Pstate   - partition root state
2061c0be3f7SWaiman Long# ISOLCPUS - isolated CPUs (<icpus>[,<icpus2>])
2071c0be3f7SWaiman Long#
2081c0be3f7SWaiman Long# Note that if there are 2 fields in ISOLCPUS, the first one is for
2091c0be3f7SWaiman Long# sched-debug matching which includes offline CPUs and single-CPU partitions
2101c0be3f7SWaiman Long# while the second one is for matching cpuset.cpus.isolated.
2111c0be3f7SWaiman Long#
212a8c52ebaSWaiman LongSETUP_A123_PARTITIONS="C1-3:P1:S+ C2-3:P1:S+ C3:P1"
213a8c52ebaSWaiman LongTEST_MATRIX=(
214105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
215105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
216105f3fe9SWaiman Long	"   C0-1     .      .    C2-3    S+    C4-5     .      .     0 A2:0-1"
217105f3fe9SWaiman Long	"   C0-1     .      .    C2-3    P1      .      .      .     0 "
218105f3fe9SWaiman Long	"   C0-1     .      .    C2-3   P1:S+ C0-1:P1   .      .     0 "
219105f3fe9SWaiman Long	"   C0-1     .      .    C2-3   P1:S+  C1:P1    .      .     0 "
220105f3fe9SWaiman Long	"  C0-1:S+   .      .    C2-3     .      .      .     P1     0 "
221105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+     C1      .      .     0 "
222105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+    C1:P1    .      .     0 "
223105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+    C1:P1    .     P1     0 "
224105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3   C4-5     .      .      .     0 A1:4-5"
225105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3  S+:C4-5   .      .      .     0 A1:4-5"
226105f3fe9SWaiman Long	"   C0-1     .      .   C2-3:P1   .      .      .     C2     0 "
227105f3fe9SWaiman Long	"   C0-1     .      .   C2-3:P1   .      .      .    C4-5    0 B1:4-5"
228*e8a457b7SWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .      .      .      .      .     0 A1:0-1|A2:2-3|XA2:2-3"
229*e8a457b7SWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     C1-3    .      .      .     0 A1:1|A2:2-3|XA2:2-3"
230*e8a457b7SWaiman Long	"C2-3:P1:S+  C3:P1  .      .     C3      .      .      .     0 A1:|A2:3|XA2:3 A1:P1|A2:P1"
23165046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     C3      P0     .      .     0 A1:3|A2:3 A1:P1|A2:P0"
23265046b5eSWaiman Long	"C2-3:P1:S+  C2:P1  .      .     C2-4    .      .      .     0 A1:3-4|A2:2"
23365046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     C3      .      .     C0-2   0 A1:|B1:0-2 A1:P1|A2:P1"
23465046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     C2-3    .      .      .     0 A1:|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
235a8c52ebaSWaiman Long
236a8c52ebaSWaiman Long	# CPU offlining cases:
23765046b5eSWaiman Long	"   C0-1     .      .    C2-3    S+    C4-5     .     O2=0   0 A1:0-1|B1:3"
23865046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O2=0    .      .      .     0 A1:0-1|A2:3"
23965046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O2=0   O2=1    .      .     0 A1:0-1|A2:2-3"
24065046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O1=0    .      .      .     0 A1:0|A2:2-3"
24165046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O1=0   O1=1    .      .     0 A1:0-1|A2:2-3"
24265046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O3=0   O3=1    .      .     0 A1:2|A2:3 A1:P1|A2:P1"
24365046b5eSWaiman Long	"C2-3:P1:S+  C3:P2  .      .     O3=0   O3=1    .      .     0 A1:2|A2:3 A1:P1|A2:P2"
24465046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O2=0   O2=1    .      .     0 A1:2|A2:3 A1:P1|A2:P1"
24565046b5eSWaiman Long	"C2-3:P1:S+  C3:P2  .      .     O2=0   O2=1    .      .     0 A1:2|A2:3 A1:P1|A2:P2"
24665046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O2=0    .      .      .     0 A1:|A2:3 A1:P1|A2:P1"
24765046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O3=0    .      .      .     0 A1:2|A2: A1:P1|A2:P1"
24865046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .    T:O2=0   .      .      .     0 A1:3|A2:3 A1:P1|A2:P-1"
24965046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .      .    T:O3=0   .      .     0 A1:2|A2:2 A1:P1|A2:P-1"
25065046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     O1=0    .      .      .     0 A1:|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
25165046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     O2=0    .      .      .     0 A1:1|A2:|A3:3 A1:P1|A2:P1|A3:P1"
25265046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     O3=0    .      .      .     0 A1:1|A2:2|A3: A1:P1|A2:P1|A3:P1"
25365046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0   .      .      .     0 A1:2-3|A2:2-3|A3:3 A1:P1|A2:P-1|A3:P-1"
25465046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .      .    T:O2=0   .      .     0 A1:1|A2:3|A3:3 A1:P1|A2:P1|A3:P-1"
25565046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .      .      .    T:O3=0   .     0 A1:1|A2:2|A3:2 A1:P1|A2:P1|A3:P-1"
25665046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0  O1=1    .      .     0 A1:1|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
25765046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .      .    T:O2=0  O2=1    .     0 A1:1|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
25865046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .      .      .    T:O3=0  O3=1   0 A1:1|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
25965046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0  O2=0   O1=1    .     0 A1:1|A2:|A3:3 A1:P1|A2:P1|A3:P1"
26065046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0  O2=0   O2=1    .     0 A1:2-3|A2:2-3|A3:3 A1:P1|A2:P-1|A3:P-1"
261a8c52ebaSWaiman Long
262105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
263105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
264105f3fe9SWaiman Long	#
265105f3fe9SWaiman Long	# Remote partition and cpuset.cpus.exclusive tests
266105f3fe9SWaiman Long	#
26765046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3     .    X2-3     .      .      .     0 A1:0-3|A2:1-3|A3:2-3|XA1:2-3"
26865046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3     .    X2-3  X2-3:P2   .      .     0 A1:0-1|A2:2-3|A3:2-3 A1:P0|A2:P2 2-3"
26965046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3     .    X2-3   X3:P2    .      .     0 A1:0-2|A2:3|A3:3 A1:P0|A2:P2 3"
27065046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3     .    X2-3   X2-3  X2-3:P2   .     0 A1:0-1|A2:1|A3:2-3 A1:P0|A3:P2 2-3"
27165046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3     .    X2-3   X2-3 X2-3:P2:C3 .     0 A1:0-1|A2:1|A3:2-3 A1:P0|A3:P2 2-3"
27265046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3   C2-3     .      .      .      P2    0 A1:0-3|A2:1-3|A3:2-3|B1:2-3 A1:P0|A3:P0|B1:P-2"
273105f3fe9SWaiman Long	" C0-3:S+ C1-3:S+ C2-3   C4-5     .      .      .      P2    0 B1:4-5 B1:P2 4-5"
27465046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3    C4    X2-3   X2-3  X2-3:P2   P2    0 A3:2-3|B1:4 A3:P2|B1:P2 2-4"
27565046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3    C4    X2-3   X2-3 X2-3:P2:C1-3 P2  0 A3:2-3|B1:4 A3:P2|B1:P2 2-4"
27665046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3    C4    X1-3  X1-3:P2   P2     .     0 A2:1|A3:2-3 A2:P2|A3:P2 1-3"
27765046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3    C4    X2-3   X2-3  X2-3:P2 P2:C4-5 0 A3:2-3|B1:4-5 A3:P2|B1:P2 2-5"
27865046b5eSWaiman Long	" C4:X0-3:S+ X1-3:S+ X2-3  .      .      P2     .      .     0 A1:4|A2:1-3|A3:1-3 A2:P2 1-3"
27965046b5eSWaiman Long	" C4:X0-3:S+ X1-3:S+ X2-3  .      .      .      P2     .     0 A1:4|A2:4|A3:2-3 A3:P2 2-3"
280105f3fe9SWaiman Long
281105f3fe9SWaiman Long	# Nested remote/local partition tests
28265046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3   C4-5   X2-3  X2-3:P1   P2     P1    0 A1:0-1|A2:|A3:2-3|B1:4-5 \
28365046b5eSWaiman Long								       A1:P0|A2:P1|A3:P2|B1:P1 2-3"
28465046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3    C4    X2-3  X2-3:P1   P2     P1    0 A1:0-1|A2:|A3:2-3|B1:4 \
28565046b5eSWaiman Long								       A1:P0|A2:P1|A3:P2|B1:P1 2-4|2-3"
28665046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3    C4    X2-3  X2-3:P1    .     P1    0 A1:0-1|A2:2-3|A3:2-3|B1:4 \
28765046b5eSWaiman Long								       A1:P0|A2:P1|A3:P0|B1:P1"
28865046b5eSWaiman Long	" C0-3:S+ C1-3:S+  C3     C4    X2-3  X2-3:P1   P2     P1    0 A1:0-1|A2:2|A3:3|B1:4 \
28965046b5eSWaiman Long								       A1:P0|A2:P1|A3:P2|B1:P1 2-4|3"
29065046b5eSWaiman Long	" C0-4:S+ C1-4:S+ C2-4     .    X2-4  X2-4:P2  X4:P1    .    0 A1:0-1|A2:2-3|A3:4 \
29165046b5eSWaiman Long								       A1:P0|A2:P2|A3:P1 2-4|2-3"
29265046b5eSWaiman Long	" C0-4:S+ C1-4:S+ C2-4     .    X2-4  X2-4:P2 X3-4:P1   .    0 A1:0-1|A2:2|A3:3-4 \
29365046b5eSWaiman Long								       A1:P0|A2:P2|A3:P1 2"
294105f3fe9SWaiman Long	" C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \
29565046b5eSWaiman Long				   .      .      X5      .      .    0 A1:0-4|A2:1-4|A3:2-4 \
296*e8a457b7SWaiman Long								       A1:P0|A2:P-2|A3:P-1 ."
297105f3fe9SWaiman Long	" C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \
29865046b5eSWaiman Long				   .      .      .      X1      .    0 A1:0-1|A2:2-4|A3:2-4 \
29965046b5eSWaiman Long								       A1:P0|A2:P2|A3:P-1 2-4"
300105f3fe9SWaiman Long
301105f3fe9SWaiman Long	# Remote partition offline tests
30265046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3     .    X2-3   X2-3 X2-3:P2:O2=0 .   0 A1:0-1|A2:1|A3:3 A1:P0|A3:P2 2-3"
30365046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3     .    X2-3   X2-3 X2-3:P2:O2=0 O2=1 0 A1:0-1|A2:1|A3:2-3 A1:P0|A3:P2 2-3"
30465046b5eSWaiman Long	" C0-3:S+ C1-3:S+  C3      .    X2-3   X2-3    P2:O3=0   .   0 A1:0-2|A2:1-2|A3: A1:P0|A3:P2 3"
30565046b5eSWaiman Long	" C0-3:S+ C1-3:S+  C3      .    X2-3   X2-3   T:P2:O3=0  .   0 A1:0-2|A2:1-2|A3:1-2 A1:P0|A3:P-2 3|"
306105f3fe9SWaiman Long
307105f3fe9SWaiman Long	# An invalidated remote partition cannot self-recover from hotplug
308*e8a457b7SWaiman Long	" C0-3:S+ C1-3:S+  C2      .    X2-3   X2-3   T:P2:O2=0 O2=1 0 A1:0-3|A2:1-3|A3:2 A1:P0|A3:P-2 ."
309105f3fe9SWaiman Long
310105f3fe9SWaiman Long	# cpus.exclusive.effective clearing test
31165046b5eSWaiman Long	" C0-3:S+ C1-3:S+  C2      .   X2-3:X    .      .      .     0 A1:0-3|A2:1-3|A3:2|XA1:"
312105f3fe9SWaiman Long
31346c521baSWaiman Long	# Invalid to valid remote partition transition test
314*e8a457b7SWaiman Long	" C0-3:S+   C1-3    .      .      .    X3:P2    .      .     0 A1:0-3|A2:1-3|XA2: A2:P-2 ."
315105f3fe9SWaiman Long	" C0-3:S+ C1-3:X3:P2
31665046b5eSWaiman Long			    .      .    X2-3    P2      .      .     0 A1:0-2|A2:3|XA2:3 A2:P2 3"
317105f3fe9SWaiman Long
318105f3fe9SWaiman Long	# Invalid to valid local partition direct transition tests
31965046b5eSWaiman Long	" C1-3:S+:P2 X4:P2  .      .      .      .      .      .     0 A1:1-3|XA1:1-3|A2:1-3:XA2: A1:P2|A2:P-2 1-3"
32065046b5eSWaiman Long	" C1-3:S+:P2 X4:P2  .      .      .    X3:P2    .      .     0 A1:1-2|XA1:1-3|A2:3:XA2:3 A1:P2|A2:P2 1-3"
32165046b5eSWaiman Long	"  C0-3:P2   .      .    C4-6   C0-4     .      .      .     0 A1:0-4|B1:4-6 A1:P-2|B1:P0"
32265046b5eSWaiman Long	"  C0-3:P2   .      .    C4-6 C0-4:C0-3  .      .      .     0 A1:0-3|B1:4-6 A1:P2|B1:P0 0-3"
323105f3fe9SWaiman Long
324105f3fe9SWaiman Long	# Local partition invalidation tests
325105f3fe9SWaiman Long	" C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \
32665046b5eSWaiman Long				   .      .      .      .      .     0 A1:1|A2:2|A3:3 A1:P2|A2:P2|A3:P2 1-3"
327105f3fe9SWaiman Long	" C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \
32865046b5eSWaiman Long				   .      .     X4      .      .     0 A1:1-3|A2:1-3|A3:2-3|XA2:|XA3: A1:P2|A2:P-2|A3:P-2 1-3"
329105f3fe9SWaiman Long	" C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \
33065046b5eSWaiman Long				   .      .    C4:X     .      .     0 A1:1-3|A2:1-3|A3:2-3|XA2:|XA3: A1:P2|A2:P-2|A3:P-2 1-3"
33146c521baSWaiman Long	# Local partition CPU change tests
33265046b5eSWaiman Long	" C0-5:S+:P2 C4-5:S+:P1 .  .      .    C3-5     .      .     0 A1:0-2|A2:3-5 A1:P2|A2:P1 0-2"
33365046b5eSWaiman Long	" C0-5:S+:P2 C4-5:S+:P1 .  .    C1-5     .      .      .     0 A1:1-3|A2:4-5 A1:P2|A2:P1 1-3"
334105f3fe9SWaiman Long
335105f3fe9SWaiman Long	# cpus_allowed/exclusive_cpus update tests
336105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \
33765046b5eSWaiman Long				   .    X:C4     .      P2     .     0 A1:4|A2:4|XA2:|XA3:|A3:4 \
338*e8a457b7SWaiman Long								       A1:P0|A3:P-2 ."
339105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \
34065046b5eSWaiman Long				   .     X1      .      P2     .     0 A1:0-3|A2:1-3|XA1:1|XA2:|XA3:|A3:2-3 \
341*e8a457b7SWaiman Long								       A1:P0|A3:P-2 ."
342105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \
34365046b5eSWaiman Long				   .      .     X3      P2     .     0 A1:0-2|A2:1-2|XA2:3|XA3:3|A3:3 \
34465046b5eSWaiman Long								       A1:P0|A3:P2 3"
345105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \
34665046b5eSWaiman Long				   .      .     X3      .      .     0 A1:0-2|A2:1-2|XA2:3|XA3:3|A3:3|XA3:3 \
34765046b5eSWaiman Long								       A1:P0|A3:P2 3"
348105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \
34965046b5eSWaiman Long				   .     X4      .      .      .     0 A1:0-3|A2:1-3|A3:2-3|XA1:4|XA2:|XA3 \
35065046b5eSWaiman Long								       A1:P0|A3:P-2"
351105f3fe9SWaiman Long
352105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
353105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
354a8c52ebaSWaiman Long	#
35592841d6eSWaiman Long	# Incorrect change to cpuset.cpus[.exclusive] invalidates partition root
356a8c52ebaSWaiman Long	#
357a8c52ebaSWaiman Long	# Adding CPUs to partition root that are not in parent's
358a8c52ebaSWaiman Long	# cpuset.cpus is allowed, but those extra CPUs are ignored.
35965046b5eSWaiman Long	"C2-3:P1:S+ C3:P1   .      .      .     C2-4    .      .     0 A1:|A2:2-3 A1:P1|A2:P1"
360a8c52ebaSWaiman Long
361a8c52ebaSWaiman Long	# Taking away all CPUs from parent or itself if there are tasks
362a8c52ebaSWaiman Long	# will make the partition invalid.
36365046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .      T     C2-3    .      .     0 A1:2-3|A2:2-3 A1:P1|A2:P-1"
36465046b5eSWaiman Long	" C3:P1:S+    C3    .      .      T      P1     .      .     0 A1:3|A2:3 A1:P1|A2:P-1"
36565046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .    T:C2-3   .      .      .     0 A1:2-3|A2:2-3|A3:3 A1:P1|A2:P-1|A3:P-1"
36665046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    . T:C2-3:C1-3 .      .      .     0 A1:1|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
367a8c52ebaSWaiman Long
368a8c52ebaSWaiman Long	# Changing a partition root to member makes child partitions invalid
36965046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .      P0     .      .      .     0 A1:2-3|A2:3 A1:P0|A2:P-1"
37065046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     C2-3    P0     .      .     0 A1:2-3|A2:2-3|A3:3 A1:P1|A2:P0|A3:P-1"
371a8c52ebaSWaiman Long
372a8c52ebaSWaiman Long	# cpuset.cpus can contains cpus not in parent's cpuset.cpus as long
373a8c52ebaSWaiman Long	# as they overlap.
37465046b5eSWaiman Long	"C2-3:P1:S+  .      .      .      .   C3-4:P1   .      .     0 A1:2|A2:3 A1:P1|A2:P1"
375a8c52ebaSWaiman Long
376a8c52ebaSWaiman Long	# Deletion of CPUs distributed to child cgroup is allowed.
37765046b5eSWaiman Long	"C0-1:P1:S+ C1      .    C2-3   C4-5     .      .      .     0 A1:4-5|A2:4-5"
378a8c52ebaSWaiman Long
379a8c52ebaSWaiman Long	# To become a valid partition root, cpuset.cpus must overlap parent's
380a8c52ebaSWaiman Long	# cpuset.cpus.
38165046b5eSWaiman Long	"  C0-1:P1   .      .    C2-3    S+   C4-5:P1   .      .     0 A1:0-1|A2:0-1 A1:P1|A2:P-1"
382a8c52ebaSWaiman Long
383a8c52ebaSWaiman Long	# Enabling partition with child cpusets is allowed
38465046b5eSWaiman Long	"  C0-1:S+  C1      .    C2-3    P1      .      .      .     0 A1:0-1|A2:1 A1:P1"
385a8c52ebaSWaiman Long
38665046b5eSWaiman Long	# A partition root with non-partition root parent is invalid| but it
387a8c52ebaSWaiman Long	# can be made valid if its parent becomes a partition root too.
38865046b5eSWaiman Long	"  C0-1:S+  C1      .    C2-3     .      P2     .      .     0 A1:0-1|A2:1 A1:P0|A2:P-2"
389*e8a457b7SWaiman Long	"  C0-1:S+ C1:P2    .    C2-3     P1     .      .      .     0 A1:0|A2:1 A1:P1|A2:P2 0-1|1"
390a8c52ebaSWaiman Long
391a8c52ebaSWaiman Long	# A non-exclusive cpuset.cpus change will invalidate partition and its siblings
39265046b5eSWaiman Long	"  C0-1:P1   .      .    C2-3   C0-2     .      .      .     0 A1:0-2|B1:2-3 A1:P-1|B1:P0"
39365046b5eSWaiman Long	"  C0-1:P1   .      .  P1:C2-3  C0-2     .      .      .     0 A1:0-2|B1:2-3 A1:P-1|B1:P-1"
39465046b5eSWaiman Long	"   C0-1     .      .  P1:C2-3  C0-2     .      .      .     0 A1:0-2|B1:2-3 A1:P0|B1:P-1"
395a8c52ebaSWaiman Long
3961c0be3f7SWaiman Long	# cpuset.cpus can overlap with sibling cpuset.cpus.exclusive but not subsumed by it
39765046b5eSWaiman Long	"   C0-3     .      .    C4-5     X5     .      .      .     0 A1:0-3|B1:4-5"
3981c0be3f7SWaiman Long
39992841d6eSWaiman Long	# Child partition root that try to take all CPUs from parent partition
40092841d6eSWaiman Long	# with tasks will remain invalid.
40165046b5eSWaiman Long	" C1-4:P1:S+ P1     .      .       .     .      .      .     0 A1:1-4|A2:1-4 A1:P1|A2:P-1"
40265046b5eSWaiman Long	" C1-4:P1:S+ P1     .      .       .   C1-4     .      .     0 A1|A2:1-4 A1:P1|A2:P1"
40365046b5eSWaiman Long	" C1-4:P1:S+ P1     .      .       T   C1-4     .      .     0 A1:1-4|A2:1-4 A1:P1|A2:P-1"
40492841d6eSWaiman Long
40592841d6eSWaiman Long	# Clearing of cpuset.cpus with a preset cpuset.cpus.exclusive shouldn't
40692841d6eSWaiman Long	# affect cpuset.cpus.exclusive.effective.
40765046b5eSWaiman Long	" C1-4:X3:S+ C1:X3  .      .       .     C      .      .     0 A2:1-4|XA2:3"
40892841d6eSWaiman Long
409*e8a457b7SWaiman Long	# cpuset.cpus can contain CPUs that overlap a sibling cpuset with cpus.exclusive
410*e8a457b7SWaiman Long	# but creating a local partition out of it is not allowed. Similarly and change
411*e8a457b7SWaiman Long	# in cpuset.cpus of a local partition that overlaps sibling exclusive CPUs will
412*e8a457b7SWaiman Long	# invalidate it.
413*e8a457b7SWaiman Long	" CX1-4:S+ CX2-4:P2 .    C5-6      .     .      .      P1    0 A1:1|A2:2-4|B1:5-6|XB1:5-6 \
414*e8a457b7SWaiman Long								       A1:P0|A2:P2:B1:P1 2-4"
415*e8a457b7SWaiman Long	" CX1-4:S+ CX2-4:P2 .    C3-6      .     .      .      P1    0 A1:1|A2:2-4|B1:5-6 \
416*e8a457b7SWaiman Long								       A1:P0|A2:P2:B1:P-1 2-4"
417*e8a457b7SWaiman Long	" CX1-4:S+ CX2-4:P2 .    C5-6      .     .      .   P1:C3-6  0 A1:1|A2:2-4|B1:5-6 \
418*e8a457b7SWaiman Long								       A1:P0|A2:P2:B1:P-1 2-4"
419*e8a457b7SWaiman Long
420105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
421105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
422a8c52ebaSWaiman Long	# Failure cases:
423a8c52ebaSWaiman Long
424a8c52ebaSWaiman Long	# A task cannot be added to a partition with no cpu
42565046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .    O2=0:T   .      .      .     1 A1:|A2:3 A1:P1|A2:P1"
426105f3fe9SWaiman Long
427105f3fe9SWaiman Long	# Changes to cpuset.cpus.exclusive that violate exclusivity rule is rejected
42865046b5eSWaiman Long	"   C0-3     .      .    C4-5   X0-3     .      .     X3-5   1 A1:0-3|B1:4-5"
4291c0be3f7SWaiman Long
4301c0be3f7SWaiman Long	# cpuset.cpus cannot be a subset of sibling cpuset.cpus.exclusive
43165046b5eSWaiman Long	"   C0-3     .      .    C4-5   X3-5     .      .      .     1 A1:0-3|B1:4-5"
432a8c52ebaSWaiman Long)
433a8c52ebaSWaiman Long
434a8c52ebaSWaiman Long#
435*e8a457b7SWaiman Long# Cpuset controller remote partition test matrix.
436*e8a457b7SWaiman Long#
437*e8a457b7SWaiman Long# Cgroup test hierarchy
438*e8a457b7SWaiman Long#
439*e8a457b7SWaiman Long#	      root
440*e8a457b7SWaiman Long#	        |
441*e8a457b7SWaiman Long#	      rtest (cpuset.cpus.exclusive=1-7)
442*e8a457b7SWaiman Long#	        |
443*e8a457b7SWaiman Long#	 +------+------+
444*e8a457b7SWaiman Long#	 |             |
445*e8a457b7SWaiman Long#	 p1            p2
446*e8a457b7SWaiman Long#     +--+--+       +--+--+
447*e8a457b7SWaiman Long#     |     |       |     |
448*e8a457b7SWaiman Long#    c11   c12     c21   c22
449*e8a457b7SWaiman Long#
450*e8a457b7SWaiman Long# REMOTE_TEST_MATRIX uses the same notational convention as TEST_MATRIX.
451*e8a457b7SWaiman Long# Only CPUs 1-7 should be used.
452*e8a457b7SWaiman Long#
453*e8a457b7SWaiman LongREMOTE_TEST_MATRIX=(
454*e8a457b7SWaiman Long	#  old-p1 old-p2 old-c11 old-c12 old-c21 old-c22
455*e8a457b7SWaiman Long	#  new-p1 new-p2 new-c11 new-c12 new-c21 new-c22 ECPUs Pstate ISOLCPUS
456*e8a457b7SWaiman Long	#  ------ ------ ------- ------- ------- ------- ----- ------ --------
457*e8a457b7SWaiman Long	" X1-3:S+ X4-6:S+ X1-2     X3     X4-5     X6 \
458*e8a457b7SWaiman Long	      .      .     P2      P2      P2      P2    c11:1-2|c12:3|c21:4-5|c22:6 \
459*e8a457b7SWaiman Long							 c11:P2|c12:P2|c21:P2|c22:P2 1-6"
460*e8a457b7SWaiman Long	" CX1-4:S+   .   X1-2:P2   C3      .       .  \
461*e8a457b7SWaiman Long	      .      .     .      C3-4     .       .     p1:3-4|c11:1-2|c12:3-4 \
462*e8a457b7SWaiman Long							 p1:P0|c11:P2|c12:P0 1-2"
463*e8a457b7SWaiman Long	" CX1-4:S+   .   X1-2:P2   .       .       .  \
464*e8a457b7SWaiman Long	    X2-4     .     .       .       .       .     p1:1,3-4|c11:2 \
465*e8a457b7SWaiman Long							 p1:P0|c11:P2 2"
466*e8a457b7SWaiman Long	" CX1-5:S+   .   X1-2:P2 X3-5:P1   .       .  \
467*e8a457b7SWaiman Long	    X2-4     .     .       .       .       .     p1:1,5|c11:2|c12:3-4 \
468*e8a457b7SWaiman Long							 p1:P0|c11:P2|c12:P1 2"
469*e8a457b7SWaiman Long	" CX1-4:S+   .   X1-2:P2 X3-4:P1   .       .  \
470*e8a457b7SWaiman Long	      .      .     X2      .       .       .     p1:1|c11:2|c12:3-4 \
471*e8a457b7SWaiman Long							 p1:P0|c11:P2|c12:P1 2"
472*e8a457b7SWaiman Long	# p1 as member, will get its effective CPUs from its parent rtest
473*e8a457b7SWaiman Long	" CX1-4:S+   .   X1-2:P2 X3-4:P1   .       .  \
474*e8a457b7SWaiman Long	      .      .     X1     CX2-4    .       .     p1:5-7|c11:1|c12:2-4 \
475*e8a457b7SWaiman Long							 p1:P0|c11:P2|c12:P1 1"
476*e8a457b7SWaiman Long	" CX1-4:S+ X5-6:P1:S+ .    .       .       .  \
477*e8a457b7SWaiman Long	      .      .   X1-2:P2  X4-5:P1  .     X1-7:P2 p1:3|c11:1-2|c12:4:c22:5-6 \
478*e8a457b7SWaiman Long							 p1:P0|p2:P1|c11:P2|c12:P1|c22:P2 \
479*e8a457b7SWaiman Long							 1-2,4-6|1-2,5-6"
480*e8a457b7SWaiman Long)
481*e8a457b7SWaiman Long
482*e8a457b7SWaiman Long#
483a8c52ebaSWaiman Long# Write to the cpu online file
484105f3fe9SWaiman Long#  $1 - <c>=<v> where <c> = cpu number, <v> value to be written
485a8c52ebaSWaiman Long#
486a8c52ebaSWaiman Longwrite_cpu_online()
487a8c52ebaSWaiman Long{
488105f3fe9SWaiman Long	CPU=${1%=*}
489105f3fe9SWaiman Long	VAL=${1#*=}
490a8c52ebaSWaiman Long	CPUFILE=//sys/devices/system/cpu/cpu${CPU}/online
491a8c52ebaSWaiman Long	if [[ $VAL -eq 0 ]]
492a8c52ebaSWaiman Long	then
493a8c52ebaSWaiman Long		OFFLINE_CPUS="$OFFLINE_CPUS $CPU"
494a8c52ebaSWaiman Long	else
495a8c52ebaSWaiman Long		[[ -n "$OFFLINE_CPUS" ]] && {
496a8c52ebaSWaiman Long			OFFLINE_CPUS=$(echo $CPU $CPU $OFFLINE_CPUS | fmt -1 |\
497a8c52ebaSWaiman Long					sort | uniq -u)
498a8c52ebaSWaiman Long		}
499a8c52ebaSWaiman Long	fi
500a8c52ebaSWaiman Long	echo $VAL > $CPUFILE
50172c6303aSWaiman Long	pause 0.05
502a8c52ebaSWaiman Long}
503a8c52ebaSWaiman Long
504a8c52ebaSWaiman Long#
505a8c52ebaSWaiman Long# Set controller state
506a8c52ebaSWaiman Long#  $1 - cgroup directory
507a8c52ebaSWaiman Long#  $2 - state
508a8c52ebaSWaiman Long#  $3 - showerr
509a8c52ebaSWaiman Long#
510a8c52ebaSWaiman Long# The presence of ":" in state means transition from one to the next.
511a8c52ebaSWaiman Long#
512a8c52ebaSWaiman Longset_ctrl_state()
513a8c52ebaSWaiman Long{
514a8c52ebaSWaiman Long	TMPMSG=/tmp/.msg_$$
515a8c52ebaSWaiman Long	CGRP=$1
516a8c52ebaSWaiman Long	STATE=$2
517105f3fe9SWaiman Long	SHOWERR=${3}
518a8c52ebaSWaiman Long	CTRL=${CTRL:=$CONTROLLER}
519a8c52ebaSWaiman Long	HASERR=0
520a8c52ebaSWaiman Long	REDIRECT="2> $TMPMSG"
521a8c52ebaSWaiman Long	[[ -z "$STATE" || "$STATE" = '.' ]] && return 0
522105f3fe9SWaiman Long	[[ $VERBOSE -gt 0 ]] && SHOWERR=1
523a8c52ebaSWaiman Long
524a8c52ebaSWaiman Long	rm -f $TMPMSG
525a8c52ebaSWaiman Long	for CMD in $(echo $STATE | sed -e "s/:/ /g")
526a8c52ebaSWaiman Long	do
527a8c52ebaSWaiman Long		TFILE=$CGRP/cgroup.procs
528a8c52ebaSWaiman Long		SFILE=$CGRP/cgroup.subtree_control
529a8c52ebaSWaiman Long		PFILE=$CGRP/cpuset.cpus.partition
530a8c52ebaSWaiman Long		CFILE=$CGRP/cpuset.cpus
531105f3fe9SWaiman Long		XFILE=$CGRP/cpuset.cpus.exclusive
532b2b2b4d0SWaiman Long		case $CMD in
533b2b2b4d0SWaiman Long		    S*) PREFIX=${CMD#?}
534a8c52ebaSWaiman Long			COMM="echo ${PREFIX}${CTRL} > $SFILE"
535a8c52ebaSWaiman Long			eval $COMM $REDIRECT
536b2b2b4d0SWaiman Long			;;
537b2b2b4d0SWaiman Long		    X*)
538105f3fe9SWaiman Long			CPUS=${CMD#?}
539105f3fe9SWaiman Long			COMM="echo $CPUS > $XFILE"
540105f3fe9SWaiman Long			eval $COMM $REDIRECT
541b2b2b4d0SWaiman Long			;;
542b2b2b4d0SWaiman Long		    CX*)
543b2b2b4d0SWaiman Long			CPUS=${CMD#??}
544b2b2b4d0SWaiman Long			COMM="echo $CPUS > $CFILE; echo $CPUS > $XFILE"
545b2b2b4d0SWaiman Long			eval $COMM $REDIRECT
546b2b2b4d0SWaiman Long			;;
547b2b2b4d0SWaiman Long		    C*) CPUS=${CMD#?}
548a8c52ebaSWaiman Long			COMM="echo $CPUS > $CFILE"
549a8c52ebaSWaiman Long			eval $COMM $REDIRECT
550b2b2b4d0SWaiman Long			;;
551b2b2b4d0SWaiman Long		    P*) VAL=${CMD#?}
552a8c52ebaSWaiman Long			case $VAL in
553a8c52ebaSWaiman Long			0)  VAL=member
554a8c52ebaSWaiman Long			    ;;
555a8c52ebaSWaiman Long			1)  VAL=root
556a8c52ebaSWaiman Long			    ;;
557a8c52ebaSWaiman Long			2)  VAL=isolated
558a8c52ebaSWaiman Long			    ;;
559a8c52ebaSWaiman Long			*)
560a8c52ebaSWaiman Long			    echo "Invalid partition state - $VAL"
561a8c52ebaSWaiman Long			    exit 1
562a8c52ebaSWaiman Long			    ;;
563a8c52ebaSWaiman Long			esac
564a8c52ebaSWaiman Long			COMM="echo $VAL > $PFILE"
565a8c52ebaSWaiman Long			eval $COMM $REDIRECT
566b2b2b4d0SWaiman Long			;;
567b2b2b4d0SWaiman Long		    O*) VAL=${CMD#?}
568a8c52ebaSWaiman Long			write_cpu_online $VAL
569b2b2b4d0SWaiman Long			;;
570b2b2b4d0SWaiman Long		    T*) COMM="echo 0 > $TFILE"
571a8c52ebaSWaiman Long			eval $COMM $REDIRECT
572b2b2b4d0SWaiman Long			;;
573b2b2b4d0SWaiman Long		    *)  echo "Unknown command: $CMD"
574b2b2b4d0SWaiman Long		        exit 1
575b2b2b4d0SWaiman Long			;;
576b2b2b4d0SWaiman Long		esac
577a8c52ebaSWaiman Long		RET=$?
578a8c52ebaSWaiman Long		[[ $RET -ne 0 ]] && {
579a8c52ebaSWaiman Long			[[ -n "$SHOWERR" ]] && {
580a8c52ebaSWaiman Long				echo "$COMM"
581a8c52ebaSWaiman Long				cat $TMPMSG
582a8c52ebaSWaiman Long			}
583a8c52ebaSWaiman Long			HASERR=1
584a8c52ebaSWaiman Long		}
585a8c52ebaSWaiman Long		pause 0.01
586a8c52ebaSWaiman Long		rm -f $TMPMSG
587a8c52ebaSWaiman Long	done
588a8c52ebaSWaiman Long	return $HASERR
589a8c52ebaSWaiman Long}
590a8c52ebaSWaiman Long
591a8c52ebaSWaiman Longset_ctrl_state_noerr()
592a8c52ebaSWaiman Long{
593a8c52ebaSWaiman Long	CGRP=$1
594a8c52ebaSWaiman Long	STATE=$2
595a8c52ebaSWaiman Long	[[ -d $CGRP ]] || mkdir $CGRP
596a8c52ebaSWaiman Long	set_ctrl_state $CGRP $STATE 1
597a8c52ebaSWaiman Long	[[ $? -ne 0 ]] && {
598a8c52ebaSWaiman Long		echo "ERROR: Failed to set $2 to cgroup $1!"
599a8c52ebaSWaiman Long		exit 1
600a8c52ebaSWaiman Long	}
601a8c52ebaSWaiman Long}
602a8c52ebaSWaiman Long
603a8c52ebaSWaiman Longonline_cpus()
604a8c52ebaSWaiman Long{
605a8c52ebaSWaiman Long	[[ -n "OFFLINE_CPUS" ]] && {
606a8c52ebaSWaiman Long		for C in $OFFLINE_CPUS
607a8c52ebaSWaiman Long		do
608105f3fe9SWaiman Long			write_cpu_online ${C}=1
609a8c52ebaSWaiman Long		done
610a8c52ebaSWaiman Long	}
611a8c52ebaSWaiman Long}
612a8c52ebaSWaiman Long
613a8c52ebaSWaiman Long#
614b2b2b4d0SWaiman Long# Remove all the test cgroup directories
615a8c52ebaSWaiman Long#
616a8c52ebaSWaiman Longreset_cgroup_states()
617a8c52ebaSWaiman Long{
618a8c52ebaSWaiman Long	echo 0 > $CGROUP2/cgroup.procs
619a8c52ebaSWaiman Long	online_cpus
620b2b2b4d0SWaiman Long	rmdir $RESET_LIST > /dev/null 2>&1
621a8c52ebaSWaiman Long}
622a8c52ebaSWaiman Long
623a8c52ebaSWaiman Longdump_states()
624a8c52ebaSWaiman Long{
625b2b2b4d0SWaiman Long	for DIR in $CGROUP_LIST
626a8c52ebaSWaiman Long	do
627105f3fe9SWaiman Long		CPUS=$DIR/cpuset.cpus
628a8c52ebaSWaiman Long		ECPUS=$DIR/cpuset.cpus.effective
629105f3fe9SWaiman Long		XCPUS=$DIR/cpuset.cpus.exclusive
630105f3fe9SWaiman Long		XECPUS=$DIR/cpuset.cpus.exclusive.effective
631a8c52ebaSWaiman Long		PRS=$DIR/cpuset.cpus.partition
632105f3fe9SWaiman Long		PCPUS=$DIR/.__DEBUG__.cpuset.cpus.subpartitions
633877c737dSWaiman Long		ISCPUS=$DIR/cpuset.cpus.isolated
634105f3fe9SWaiman Long		[[ -e $CPUS   ]] && echo "$CPUS: $(cat $CPUS)"
635105f3fe9SWaiman Long		[[ -e $XCPUS  ]] && echo "$XCPUS: $(cat $XCPUS)"
636a8c52ebaSWaiman Long		[[ -e $ECPUS  ]] && echo "$ECPUS: $(cat $ECPUS)"
637105f3fe9SWaiman Long		[[ -e $XECPUS ]] && echo "$XECPUS: $(cat $XECPUS)"
638a8c52ebaSWaiman Long		[[ -e $PRS    ]] && echo "$PRS: $(cat $PRS)"
639105f3fe9SWaiman Long		[[ -e $PCPUS  ]] && echo "$PCPUS: $(cat $PCPUS)"
64072c6303aSWaiman Long		[[ -e $ISCPUS ]] && echo "$ISCPUS: $(cat $ISCPUS)"
641a8c52ebaSWaiman Long	done
642a8c52ebaSWaiman Long}
643a8c52ebaSWaiman Long
644a8c52ebaSWaiman Long#
645b2b2b4d0SWaiman Long# Set the actual cgroup directory into $CGRP_DIR
646b2b2b4d0SWaiman Long# $1 - cgroup name
647b2b2b4d0SWaiman Long#
648b2b2b4d0SWaiman Longset_cgroup_dir()
649b2b2b4d0SWaiman Long{
650b2b2b4d0SWaiman Long	CGRP_DIR=$1
651b2b2b4d0SWaiman Long	[[ $CGRP_DIR = A2  ]] && CGRP_DIR=A1/A2
652b2b2b4d0SWaiman Long	[[ $CGRP_DIR = A3  ]] && CGRP_DIR=A1/A2/A3
653b2b2b4d0SWaiman Long	[[ $CGRP_DIR = c11 ]] && CGRP_DIR=p1/c11
654b2b2b4d0SWaiman Long	[[ $CGRP_DIR = c12 ]] && CGRP_DIR=p1/c12
655b2b2b4d0SWaiman Long	[[ $CGRP_DIR = c21 ]] && CGRP_DIR=p2/c21
656b2b2b4d0SWaiman Long	[[ $CGRP_DIR = c22 ]] && CGRP_DIR=p2/c22
657b2b2b4d0SWaiman Long}
658b2b2b4d0SWaiman Long
659b2b2b4d0SWaiman Long#
660a8c52ebaSWaiman Long# Check effective cpus
66165046b5eSWaiman Long# $1 - check string, format: <cgroup>:<cpu-list>[|<cgroup>:<cpu-list>]*
662a8c52ebaSWaiman Long#
663a8c52ebaSWaiman Longcheck_effective_cpus()
664a8c52ebaSWaiman Long{
665a8c52ebaSWaiman Long	CHK_STR=$1
66665046b5eSWaiman Long	for CHK in $(echo $CHK_STR | sed -e "s/|/ /g")
667a8c52ebaSWaiman Long	do
668a8c52ebaSWaiman Long		set -- $(echo $CHK | sed -e "s/:/ /g")
669a8c52ebaSWaiman Long		CGRP=$1
670b2b2b4d0SWaiman Long		EXPECTED_CPUS=$2
671b2b2b4d0SWaiman Long		ACTUAL_CPUS=
672105f3fe9SWaiman Long		if [[ $CGRP = X* ]]
673105f3fe9SWaiman Long		then
674105f3fe9SWaiman Long			CGRP=${CGRP#X}
675105f3fe9SWaiman Long			FILE=cpuset.cpus.exclusive.effective
676105f3fe9SWaiman Long		else
677105f3fe9SWaiman Long			FILE=cpuset.cpus.effective
678105f3fe9SWaiman Long		fi
679b2b2b4d0SWaiman Long		set_cgroup_dir $CGRP
680b2b2b4d0SWaiman Long		[[ -e $CGRP_DIR/$FILE ]] || return 1
681b2b2b4d0SWaiman Long		ACTUAL_CPUS=$(cat $CGRP_DIR/$FILE)
682b2b2b4d0SWaiman Long		[[ $EXPECTED_CPUS = $ACTUAL_CPUS ]] || return 1
683a8c52ebaSWaiman Long	done
684a8c52ebaSWaiman Long}
685a8c52ebaSWaiman Long
686a8c52ebaSWaiman Long#
687a8c52ebaSWaiman Long# Check cgroup states
68865046b5eSWaiman Long#  $1 - check string, format: <cgroup>:<state>[|<cgroup>:<state>]*
689a8c52ebaSWaiman Long#
690a8c52ebaSWaiman Longcheck_cgroup_states()
691a8c52ebaSWaiman Long{
692a8c52ebaSWaiman Long	CHK_STR=$1
69365046b5eSWaiman Long	for CHK in $(echo $CHK_STR | sed -e "s/|/ /g")
694a8c52ebaSWaiman Long	do
695a8c52ebaSWaiman Long		set -- $(echo $CHK | sed -e "s/:/ /g")
696a8c52ebaSWaiman Long		CGRP=$1
697b2b2b4d0SWaiman Long		EXPECTED_STATE=$2
698a8c52ebaSWaiman Long		FILE=
699b2b2b4d0SWaiman Long		EVAL=$(expr substr $EXPECTED_STATE 2 2)
700a8c52ebaSWaiman Long
701b2b2b4d0SWaiman Long		set_cgroup_dir $CGRP
702b2b2b4d0SWaiman Long		case $EXPECTED_STATE in
7031c0be3f7SWaiman Long			P*) FILE=$CGRP_DIR/cpuset.cpus.partition
704a8c52ebaSWaiman Long			    ;;
705b2b2b4d0SWaiman Long			*)  echo "Unknown state: $EXPECTED_STATE!"
706a8c52ebaSWaiman Long			    exit 1
707a8c52ebaSWaiman Long			    ;;
708a8c52ebaSWaiman Long		esac
709b2b2b4d0SWaiman Long		ACTUAL_STATE=$(cat $FILE)
710a8c52ebaSWaiman Long
711b2b2b4d0SWaiman Long		case "$ACTUAL_STATE" in
712a8c52ebaSWaiman Long			member) VAL=0
713a8c52ebaSWaiman Long				;;
714a8c52ebaSWaiman Long			root)	VAL=1
715a8c52ebaSWaiman Long				;;
716a8c52ebaSWaiman Long			isolated)
717a8c52ebaSWaiman Long				VAL=2
718a8c52ebaSWaiman Long				;;
719a8c52ebaSWaiman Long			"root invalid"*)
720a8c52ebaSWaiman Long				VAL=-1
721a8c52ebaSWaiman Long				;;
722a8c52ebaSWaiman Long			"isolated invalid"*)
723a8c52ebaSWaiman Long				VAL=-2
724a8c52ebaSWaiman Long				;;
725a8c52ebaSWaiman Long		esac
726a8c52ebaSWaiman Long		[[ $EVAL != $VAL ]] && return 1
7271c0be3f7SWaiman Long
7281c0be3f7SWaiman Long		#
7291c0be3f7SWaiman Long		# For root partition, dump sched-domains info to console if
7301c0be3f7SWaiman Long		# verbose mode set for manual comparison with sched debug info.
7311c0be3f7SWaiman Long		#
7321c0be3f7SWaiman Long		[[ $VAL -eq 1 && $VERBOSE -gt 0 ]] && {
7331c0be3f7SWaiman Long			DOMS=$(cat $CGRP_DIR/cpuset.cpus.effective)
7341c0be3f7SWaiman Long			[[ -n "$DOMS" ]] &&
735b2b2b4d0SWaiman Long				echo " [$CGRP_DIR] sched-domain: $DOMS" > $CONSOLE
7361c0be3f7SWaiman Long		}
737a8c52ebaSWaiman Long	done
738a8c52ebaSWaiman Long	return 0
739a8c52ebaSWaiman Long}
740a8c52ebaSWaiman Long
741a8c52ebaSWaiman Long#
742105f3fe9SWaiman Long# Get isolated (including offline) CPUs by looking at
743877c737dSWaiman Long# /sys/kernel/debug/sched/domains and cpuset.cpus.isolated control file,
74472c6303aSWaiman Long# if available, and compare that with the expected value.
745105f3fe9SWaiman Long#
74672c6303aSWaiman Long# Note that isolated CPUs from the sched/domains context include offline
74772c6303aSWaiman Long# CPUs as well as CPUs in non-isolated 1-CPU partition. Those CPUs may
748877c737dSWaiman Long# not be included in the cpuset.cpus.isolated control file which contains
74943a17fcfSWaiman Long# only CPUs in isolated partitions as well as those that are isolated at
75043a17fcfSWaiman Long# boot time.
751105f3fe9SWaiman Long#
75272c6303aSWaiman Long# $1 - expected isolated cpu list(s) <isolcpus1>{,<isolcpus2>}
75372c6303aSWaiman Long# <isolcpus1> - expected sched/domains value
754877c737dSWaiman Long# <isolcpus2> - cpuset.cpus.isolated value = <isolcpus1> if not defined
755105f3fe9SWaiman Long#
756105f3fe9SWaiman Longcheck_isolcpus()
757105f3fe9SWaiman Long{
758b2b2b4d0SWaiman Long	EXPECTED_ISOLCPUS=$1
759b2b2b4d0SWaiman Long	ISCPUS=${CGROUP2}/cpuset.cpus.isolated
760b2b2b4d0SWaiman Long	ISOLCPUS=$(cat $ISCPUS)
761105f3fe9SWaiman Long	LASTISOLCPU=
762105f3fe9SWaiman Long	SCHED_DOMAINS=/sys/kernel/debug/sched/domains
763b2b2b4d0SWaiman Long	if [[ $EXPECTED_ISOLCPUS = . ]]
76472c6303aSWaiman Long	then
765b2b2b4d0SWaiman Long		EXPECTED_ISOLCPUS=
766b2b2b4d0SWaiman Long		EXPECTED_SDOMAIN=
767b2b2b4d0SWaiman Long	elif [[ $(expr $EXPECTED_ISOLCPUS : ".*|.*") > 0 ]]
76872c6303aSWaiman Long	then
769b2b2b4d0SWaiman Long		set -- $(echo $EXPECTED_ISOLCPUS | sed -e "s/|/ /g")
770b2b2b4d0SWaiman Long		EXPECTED_ISOLCPUS=$2
771b2b2b4d0SWaiman Long		EXPECTED_SDOMAIN=$1
77272c6303aSWaiman Long	else
773b2b2b4d0SWaiman Long		EXPECTED_SDOMAIN=$EXPECTED_ISOLCPUS
77472c6303aSWaiman Long	fi
77572c6303aSWaiman Long
77672c6303aSWaiman Long	#
7779b496a8bSWaiman Long	# Appending pre-isolated CPUs
7789b496a8bSWaiman Long	# Even though CPU #8 isn't used for testing, it can't be pre-isolated
7799b496a8bSWaiman Long	# to make appending those CPUs easier.
7809b496a8bSWaiman Long	#
7819b496a8bSWaiman Long	[[ -n "$BOOT_ISOLCPUS" ]] && {
782b2b2b4d0SWaiman Long		EXPECTED_ISOLCPUS=${EXPECTED_ISOLCPUS:+${EXPECTED_ISOLCPUS},}${BOOT_ISOLCPUS}
783b2b2b4d0SWaiman Long		EXPECTED_SDOMAIN=${EXPECTED_SDOMAIN:+${EXPECTED_SDOMAIN},}${BOOT_ISOLCPUS}
7849b496a8bSWaiman Long	}
7859b496a8bSWaiman Long
7869b496a8bSWaiman Long	#
78743a17fcfSWaiman Long	# Check cpuset.cpus.isolated cpumask
78872c6303aSWaiman Long	#
789b2b2b4d0SWaiman Long	[[ "$EXPECTED_ISOLCPUS" != "$ISOLCPUS" ]] && {
79072c6303aSWaiman Long		# Take a 50ms pause and try again
79172c6303aSWaiman Long		pause 0.05
79272c6303aSWaiman Long		ISOLCPUS=$(cat $ISCPUS)
79372c6303aSWaiman Long	}
794b2b2b4d0SWaiman Long	[[ "$EXPECTED_ISOLCPUS" != "$ISOLCPUS" ]] && return 1
79572c6303aSWaiman Long	ISOLCPUS=
796b2b2b4d0SWaiman Long	EXPECTED_ISOLCPUS=$EXPECTED_SDOMAIN
79772c6303aSWaiman Long
79872c6303aSWaiman Long	#
79972c6303aSWaiman Long	# Use the sched domain in debugfs to check isolated CPUs, if available
80072c6303aSWaiman Long	#
801105f3fe9SWaiman Long	[[ -d $SCHED_DOMAINS ]] || return 0
802105f3fe9SWaiman Long
803105f3fe9SWaiman Long	for ((CPU=0; CPU < $NR_CPUS; CPU++))
804105f3fe9SWaiman Long	do
805105f3fe9SWaiman Long		[[ -n "$(ls ${SCHED_DOMAINS}/cpu$CPU)" ]] && continue
806105f3fe9SWaiman Long
807105f3fe9SWaiman Long		if [[ -z "$LASTISOLCPU" ]]
808105f3fe9SWaiman Long		then
809105f3fe9SWaiman Long			ISOLCPUS=$CPU
810105f3fe9SWaiman Long			LASTISOLCPU=$CPU
811105f3fe9SWaiman Long		elif [[ "$LASTISOLCPU" -eq $((CPU - 1)) ]]
812105f3fe9SWaiman Long		then
813105f3fe9SWaiman Long			echo $ISOLCPUS | grep -q "\<$LASTISOLCPU\$"
814105f3fe9SWaiman Long			if [[ $? -eq 0 ]]
815105f3fe9SWaiman Long			then
816105f3fe9SWaiman Long				ISOLCPUS=${ISOLCPUS}-
817105f3fe9SWaiman Long			fi
818105f3fe9SWaiman Long			LASTISOLCPU=$CPU
819105f3fe9SWaiman Long		else
820105f3fe9SWaiman Long			if [[ $ISOLCPUS = *- ]]
821105f3fe9SWaiman Long			then
822105f3fe9SWaiman Long				ISOLCPUS=${ISOLCPUS}$LASTISOLCPU
823105f3fe9SWaiman Long			fi
824105f3fe9SWaiman Long			ISOLCPUS=${ISOLCPUS},$CPU
825105f3fe9SWaiman Long			LASTISOLCPU=$CPU
826105f3fe9SWaiman Long		fi
827105f3fe9SWaiman Long	done
828105f3fe9SWaiman Long	[[ "$ISOLCPUS" = *- ]] && ISOLCPUS=${ISOLCPUS}$LASTISOLCPU
82943a17fcfSWaiman Long
830b2b2b4d0SWaiman Long	[[ "$EXPECTED_SDOMAIN" = "$ISOLCPUS" ]]
831105f3fe9SWaiman Long}
832105f3fe9SWaiman Long
833105f3fe9SWaiman Longtest_fail()
834105f3fe9SWaiman Long{
835105f3fe9SWaiman Long	TESTNUM=$1
836105f3fe9SWaiman Long	TESTTYPE=$2
837105f3fe9SWaiman Long	ADDINFO=$3
838105f3fe9SWaiman Long	echo "Test $TEST[$TESTNUM] failed $TESTTYPE check!"
839105f3fe9SWaiman Long	[[ -n "$ADDINFO" ]] && echo "*** $ADDINFO ***"
840105f3fe9SWaiman Long	eval echo \${$TEST[$I]}
841105f3fe9SWaiman Long	echo
842105f3fe9SWaiman Long	dump_states
843105f3fe9SWaiman Long	exit 1
844105f3fe9SWaiman Long}
845105f3fe9SWaiman Long
846105f3fe9SWaiman Long#
84743a17fcfSWaiman Long# Check to see if there are unexpected isolated CPUs left beyond the boot
84843a17fcfSWaiman Long# time isolated ones.
84972c6303aSWaiman Long#
85072c6303aSWaiman Longnull_isolcpus_check()
85172c6303aSWaiman Long{
85272c6303aSWaiman Long	[[ $VERBOSE -gt 0 ]] || return 0
853877c737dSWaiman Long	# Retry a few times before printing error
854877c737dSWaiman Long	RETRY=0
85543ee4014SWaiman Long	while [[ $RETRY -lt 8 ]]
856877c737dSWaiman Long	do
85743ee4014SWaiman Long		pause 0.02
85872c6303aSWaiman Long		check_isolcpus "."
859877c737dSWaiman Long		[[ $? -eq 0 ]] && return 0
860877c737dSWaiman Long		((RETRY++))
861877c737dSWaiman Long	done
86272c6303aSWaiman Long	echo "Unexpected isolated CPUs: $ISOLCPUS"
86372c6303aSWaiman Long	dump_states
86472c6303aSWaiman Long	exit 1
86572c6303aSWaiman Long}
86672c6303aSWaiman Long
86772c6303aSWaiman Long#
868b2b2b4d0SWaiman Long# Check state transition test result
869b2b2b4d0SWaiman Long#  $1 - Test number
870b2b2b4d0SWaiman Long#  $2 - Expected effective CPU values
871b2b2b4d0SWaiman Long#  $3 - Expected partition states
872b2b2b4d0SWaiman Long#  $4 - Expected isolated CPUs
873b2b2b4d0SWaiman Long#
874b2b2b4d0SWaiman Longcheck_test_results()
875b2b2b4d0SWaiman Long{
876b2b2b4d0SWaiman Long	_NR=$1
877b2b2b4d0SWaiman Long	_ECPUS="$2"
878b2b2b4d0SWaiman Long	_PSTATES="$3"
879b2b2b4d0SWaiman Long	_ISOLCPUS="$4"
880b2b2b4d0SWaiman Long
881b2b2b4d0SWaiman Long	[[ -n "$_ECPUS" && "$_ECPUS" != . ]] && {
882b2b2b4d0SWaiman Long		check_effective_cpus $_ECPUS
883b2b2b4d0SWaiman Long		[[ $? -ne 0 ]] && test_fail $_NR "effective CPU" \
884b2b2b4d0SWaiman Long			 "Cgroup $CGRP: expected $EXPECTED_CPUS, got $ACTUAL_CPUS"
885b2b2b4d0SWaiman Long	}
886b2b2b4d0SWaiman Long
887b2b2b4d0SWaiman Long	[[ -n "$_PSTATES" && "$_PSTATES" != . ]] && {
888b2b2b4d0SWaiman Long		check_cgroup_states $_PSTATES
889b2b2b4d0SWaiman Long		[[ $? -ne 0 ]] && test_fail $_NR states \
890b2b2b4d0SWaiman Long			"Cgroup $CGRP: expected $EXPECTED_STATE, got $ACTUAL_STATE"
891b2b2b4d0SWaiman Long	}
892b2b2b4d0SWaiman Long
893b2b2b4d0SWaiman Long	# Compare the expected isolated CPUs with the actual ones,
894b2b2b4d0SWaiman Long	# if available
895b2b2b4d0SWaiman Long	[[ -n "$_ISOLCPUS" ]] && {
896b2b2b4d0SWaiman Long		check_isolcpus $_ISOLCPUS
897b2b2b4d0SWaiman Long		[[ $? -ne 0 ]] && {
898b2b2b4d0SWaiman Long			[[ -n "$BOOT_ISOLCPUS" ]] && _ISOLCPUS=${_ISOLCPUS},${BOOT_ISOLCPUS}
899b2b2b4d0SWaiman Long			test_fail $_NR "isolated CPU" \
900b2b2b4d0SWaiman Long				"Expect $_ISOLCPUS, get $ISOLCPUS instead"
901b2b2b4d0SWaiman Long		}
902b2b2b4d0SWaiman Long	}
903b2b2b4d0SWaiman Long	reset_cgroup_states
904b2b2b4d0SWaiman Long	#
905b2b2b4d0SWaiman Long	# Check to see if effective cpu list changes
906b2b2b4d0SWaiman Long	#
907b2b2b4d0SWaiman Long	_NEWLIST=$(cat $CGROUP2/cpuset.cpus.effective)
908b2b2b4d0SWaiman Long	RETRY=0
909b2b2b4d0SWaiman Long	while [[ $_NEWLIST != $CPULIST && $RETRY -lt 8 ]]
910b2b2b4d0SWaiman Long	do
911b2b2b4d0SWaiman Long		# Wait a bit longer & recheck a few times
912b2b2b4d0SWaiman Long		pause 0.02
913b2b2b4d0SWaiman Long		((RETRY++))
914b2b2b4d0SWaiman Long		_NEWLIST=$(cat $CGROUP2/cpuset.cpus.effective)
915b2b2b4d0SWaiman Long	done
916b2b2b4d0SWaiman Long	[[ $_NEWLIST != $CPULIST ]] && {
917b2b2b4d0SWaiman Long		echo "Effective cpus changed to $_NEWLIST after test $_NR!"
918b2b2b4d0SWaiman Long		exit 1
919b2b2b4d0SWaiman Long	}
920b2b2b4d0SWaiman Long	null_isolcpus_check
921b2b2b4d0SWaiman Long	[[ $VERBOSE -gt 0 ]] && echo "Test $I done."
922b2b2b4d0SWaiman Long}
923b2b2b4d0SWaiman Long
924b2b2b4d0SWaiman Long#
925a8c52ebaSWaiman Long# Run cpuset state transition test
926a8c52ebaSWaiman Long#  $1 - test matrix name
927a8c52ebaSWaiman Long#
928a8c52ebaSWaiman Long# This test is somewhat fragile as delays (sleep x) are added in various
929a8c52ebaSWaiman Long# places to make sure state changes are fully propagated before the next
930a8c52ebaSWaiman Long# action. These delays may need to be adjusted if running in a slower machine.
931a8c52ebaSWaiman Long#
932a8c52ebaSWaiman Longrun_state_test()
933a8c52ebaSWaiman Long{
934a8c52ebaSWaiman Long	TEST=$1
935a8c52ebaSWaiman Long	CONTROLLER=cpuset
936b2b2b4d0SWaiman Long	CGROUP_LIST=". A1 A1/A2 A1/A2/A3 B1"
937b2b2b4d0SWaiman Long	RESET_LIST="A1/A2/A3 A1/A2 A1 B1"
938a8c52ebaSWaiman Long	I=0
939a8c52ebaSWaiman Long	eval CNT="\${#$TEST[@]}"
940a8c52ebaSWaiman Long
941a8c52ebaSWaiman Long	reset_cgroup_states
942a8c52ebaSWaiman Long	console_msg "Running state transition test ..."
943a8c52ebaSWaiman Long
944a8c52ebaSWaiman Long	while [[ $I -lt $CNT ]]
945a8c52ebaSWaiman Long	do
94643ee4014SWaiman Long		echo "Running test $I ..." > $CONSOLE
947105f3fe9SWaiman Long		[[ $VERBOSE -gt 1 ]] && {
948105f3fe9SWaiman Long			echo ""
949105f3fe9SWaiman Long			eval echo \${$TEST[$I]}
950105f3fe9SWaiman Long		}
951a8c52ebaSWaiman Long		eval set -- "\${$TEST[$I]}"
952105f3fe9SWaiman Long		OLD_A1=$1
953105f3fe9SWaiman Long		OLD_A2=$2
954105f3fe9SWaiman Long		OLD_A3=$3
955105f3fe9SWaiman Long		OLD_B1=$4
956105f3fe9SWaiman Long		NEW_A1=$5
957105f3fe9SWaiman Long		NEW_A2=$6
958105f3fe9SWaiman Long		NEW_A3=$7
959105f3fe9SWaiman Long		NEW_B1=$8
960105f3fe9SWaiman Long		RESULT=$9
961105f3fe9SWaiman Long		ECPUS=${10}
962105f3fe9SWaiman Long		STATES=${11}
963105f3fe9SWaiman Long		ICPUS=${12}
964a8c52ebaSWaiman Long
965a8c52ebaSWaiman Long		set_ctrl_state_noerr A1       $OLD_A1
966a8c52ebaSWaiman Long		set_ctrl_state_noerr A1/A2    $OLD_A2
967a8c52ebaSWaiman Long		set_ctrl_state_noerr A1/A2/A3 $OLD_A3
968*e8a457b7SWaiman Long		set_ctrl_state_noerr B1       $OLD_B1
969*e8a457b7SWaiman Long
970a8c52ebaSWaiman Long		RETVAL=0
971a8c52ebaSWaiman Long		set_ctrl_state A1       $NEW_A1; ((RETVAL += $?))
972a8c52ebaSWaiman Long		set_ctrl_state A1/A2    $NEW_A2; ((RETVAL += $?))
973a8c52ebaSWaiman Long		set_ctrl_state A1/A2/A3 $NEW_A3; ((RETVAL += $?))
974a8c52ebaSWaiman Long		set_ctrl_state B1       $NEW_B1; ((RETVAL += $?))
975a8c52ebaSWaiman Long
976105f3fe9SWaiman Long		[[ $RETVAL -ne $RESULT ]] && test_fail $I result
977a8c52ebaSWaiman Long
978b2b2b4d0SWaiman Long		check_test_results $I "$ECPUS" "$STATES" "$ICPUS"
979a8c52ebaSWaiman Long		((I++))
980a8c52ebaSWaiman Long	done
981a8c52ebaSWaiman Long	echo "All $I tests of $TEST PASSED."
982a8c52ebaSWaiman Long}
983a8c52ebaSWaiman Long
984a8c52ebaSWaiman Long#
985*e8a457b7SWaiman Long# Run cpuset remote partition state transition test
986*e8a457b7SWaiman Long#  $1 - test matrix name
987*e8a457b7SWaiman Long#
988*e8a457b7SWaiman Longrun_remote_state_test()
989*e8a457b7SWaiman Long{
990*e8a457b7SWaiman Long	TEST=$1
991*e8a457b7SWaiman Long	CONTROLLER=cpuset
992*e8a457b7SWaiman Long	[[ -d rtest ]] || mkdir rtest
993*e8a457b7SWaiman Long	cd rtest
994*e8a457b7SWaiman Long	echo +cpuset > cgroup.subtree_control
995*e8a457b7SWaiman Long	echo "1-7" > cpuset.cpus
996*e8a457b7SWaiman Long	echo "1-7" > cpuset.cpus.exclusive
997*e8a457b7SWaiman Long	CGROUP_LIST=".. . p1 p2 p1/c11 p1/c12 p2/c21 p2/c22"
998*e8a457b7SWaiman Long	RESET_LIST="p1/c11 p1/c12 p2/c21 p2/c22 p1 p2"
999*e8a457b7SWaiman Long	I=0
1000*e8a457b7SWaiman Long	eval CNT="\${#$TEST[@]}"
1001*e8a457b7SWaiman Long
1002*e8a457b7SWaiman Long	reset_cgroup_states
1003*e8a457b7SWaiman Long	console_msg "Running remote partition state transition test ..."
1004*e8a457b7SWaiman Long
1005*e8a457b7SWaiman Long	while [[ $I -lt $CNT ]]
1006*e8a457b7SWaiman Long	do
1007*e8a457b7SWaiman Long		echo "Running test $I ..." > $CONSOLE
1008*e8a457b7SWaiman Long		[[ $VERBOSE -gt 1 ]] && {
1009*e8a457b7SWaiman Long			echo ""
1010*e8a457b7SWaiman Long			eval echo \${$TEST[$I]}
1011*e8a457b7SWaiman Long		}
1012*e8a457b7SWaiman Long		eval set -- "\${$TEST[$I]}"
1013*e8a457b7SWaiman Long		OLD_p1=$1
1014*e8a457b7SWaiman Long		OLD_p2=$2
1015*e8a457b7SWaiman Long		OLD_c11=$3
1016*e8a457b7SWaiman Long		OLD_c12=$4
1017*e8a457b7SWaiman Long		OLD_c21=$5
1018*e8a457b7SWaiman Long		OLD_c22=$6
1019*e8a457b7SWaiman Long		NEW_p1=$7
1020*e8a457b7SWaiman Long		NEW_p2=$8
1021*e8a457b7SWaiman Long		NEW_c11=$9
1022*e8a457b7SWaiman Long		NEW_c12=${10}
1023*e8a457b7SWaiman Long		NEW_c21=${11}
1024*e8a457b7SWaiman Long		NEW_c22=${12}
1025*e8a457b7SWaiman Long		ECPUS=${13}
1026*e8a457b7SWaiman Long		STATES=${14}
1027*e8a457b7SWaiman Long		ICPUS=${15}
1028*e8a457b7SWaiman Long
1029*e8a457b7SWaiman Long		set_ctrl_state_noerr p1     $OLD_p1
1030*e8a457b7SWaiman Long		set_ctrl_state_noerr p2     $OLD_p2
1031*e8a457b7SWaiman Long		set_ctrl_state_noerr p1/c11 $OLD_c11
1032*e8a457b7SWaiman Long		set_ctrl_state_noerr p1/c12 $OLD_c12
1033*e8a457b7SWaiman Long		set_ctrl_state_noerr p2/c21 $OLD_c21
1034*e8a457b7SWaiman Long		set_ctrl_state_noerr p2/c22 $OLD_c22
1035*e8a457b7SWaiman Long
1036*e8a457b7SWaiman Long		RETVAL=0
1037*e8a457b7SWaiman Long		set_ctrl_state p1     $NEW_p1 ; ((RETVAL += $?))
1038*e8a457b7SWaiman Long		set_ctrl_state p2     $NEW_p2 ; ((RETVAL += $?))
1039*e8a457b7SWaiman Long		set_ctrl_state p1/c11 $NEW_c11; ((RETVAL += $?))
1040*e8a457b7SWaiman Long		set_ctrl_state p1/c12 $NEW_c12; ((RETVAL += $?))
1041*e8a457b7SWaiman Long		set_ctrl_state p2/c21 $NEW_c21; ((RETVAL += $?))
1042*e8a457b7SWaiman Long		set_ctrl_state p2/c22 $NEW_c22; ((RETVAL += $?))
1043*e8a457b7SWaiman Long
1044*e8a457b7SWaiman Long		[[ $RETVAL -ne 0 ]] && test_fail $I result
1045*e8a457b7SWaiman Long
1046*e8a457b7SWaiman Long		check_test_results $I "$ECPUS" "$STATES" "$ICPUS"
1047*e8a457b7SWaiman Long		((I++))
1048*e8a457b7SWaiman Long	done
1049*e8a457b7SWaiman Long	cd ..
1050*e8a457b7SWaiman Long	rmdir rtest
1051*e8a457b7SWaiman Long	echo "All $I tests of $TEST PASSED."
1052*e8a457b7SWaiman Long}
1053*e8a457b7SWaiman Long
1054*e8a457b7SWaiman Long#
105514060dfcSWaiman Long# Testing the new "isolated" partition root type
105614060dfcSWaiman Long#
105714060dfcSWaiman Longtest_isolated()
105814060dfcSWaiman Long{
105914060dfcSWaiman Long	cd $CGROUP2/test
106014060dfcSWaiman Long	echo 2-3 > cpuset.cpus
106114060dfcSWaiman Long	TYPE=$(cat cpuset.cpus.partition)
106214060dfcSWaiman Long	[[ $TYPE = member ]] || echo member > cpuset.cpus.partition
106314060dfcSWaiman Long
106414060dfcSWaiman Long	console_msg "Change from member to root"
106514060dfcSWaiman Long	test_partition root
106614060dfcSWaiman Long
106714060dfcSWaiman Long	console_msg "Change from root to isolated"
106814060dfcSWaiman Long	test_partition isolated
106914060dfcSWaiman Long
107014060dfcSWaiman Long	console_msg "Change from isolated to member"
107114060dfcSWaiman Long	test_partition member
107214060dfcSWaiman Long
107314060dfcSWaiman Long	console_msg "Change from member to isolated"
107414060dfcSWaiman Long	test_partition isolated
107514060dfcSWaiman Long
107614060dfcSWaiman Long	console_msg "Change from isolated to root"
107714060dfcSWaiman Long	test_partition root
107814060dfcSWaiman Long
107914060dfcSWaiman Long	console_msg "Change from root to member"
108014060dfcSWaiman Long	test_partition member
108114060dfcSWaiman Long
108214060dfcSWaiman Long	#
108314060dfcSWaiman Long	# Testing partition root with no cpu
108414060dfcSWaiman Long	#
108514060dfcSWaiman Long	console_msg "Distribute all cpus to child partition"
108614060dfcSWaiman Long	echo +cpuset > cgroup.subtree_control
108714060dfcSWaiman Long	test_partition root
108814060dfcSWaiman Long
108914060dfcSWaiman Long	mkdir A1
109014060dfcSWaiman Long	cd A1
109114060dfcSWaiman Long	echo 2-3 > cpuset.cpus
109214060dfcSWaiman Long	test_partition root
109314060dfcSWaiman Long	test_effective_cpus 2-3
109414060dfcSWaiman Long	cd ..
109514060dfcSWaiman Long	test_effective_cpus ""
109614060dfcSWaiman Long
109714060dfcSWaiman Long	console_msg "Moving task to partition test"
109814060dfcSWaiman Long	test_add_proc "No space left"
109914060dfcSWaiman Long	cd A1
110014060dfcSWaiman Long	test_add_proc ""
110114060dfcSWaiman Long	cd ..
110214060dfcSWaiman Long
110314060dfcSWaiman Long	console_msg "Shrink and expand child partition"
110414060dfcSWaiman Long	cd A1
110514060dfcSWaiman Long	echo 2 > cpuset.cpus
110614060dfcSWaiman Long	cd ..
110714060dfcSWaiman Long	test_effective_cpus 3
110814060dfcSWaiman Long	cd A1
110914060dfcSWaiman Long	echo 2-3 > cpuset.cpus
111014060dfcSWaiman Long	cd ..
111114060dfcSWaiman Long	test_effective_cpus ""
111214060dfcSWaiman Long
111314060dfcSWaiman Long	# Cleaning up
111414060dfcSWaiman Long	console_msg "Cleaning up"
111514060dfcSWaiman Long	echo $$ > $CGROUP2/cgroup.procs
111614060dfcSWaiman Long	[[ -d A1 ]] && rmdir A1
111772c6303aSWaiman Long	null_isolcpus_check
1118b2b2b4d0SWaiman Long	pause 0.05
111914060dfcSWaiman Long}
112014060dfcSWaiman Long
112114060dfcSWaiman Long#
1122a8c52ebaSWaiman Long# Wait for inotify event for the given file and read it
1123a8c52ebaSWaiman Long# $1: cgroup file to wait for
1124a8c52ebaSWaiman Long# $2: file to store the read result
1125a8c52ebaSWaiman Long#
1126a8c52ebaSWaiman Longwait_inotify()
1127a8c52ebaSWaiman Long{
1128a8c52ebaSWaiman Long	CGROUP_FILE=$1
1129a8c52ebaSWaiman Long	OUTPUT_FILE=$2
1130a8c52ebaSWaiman Long
1131a8c52ebaSWaiman Long	$WAIT_INOTIFY $CGROUP_FILE
1132a8c52ebaSWaiman Long	cat $CGROUP_FILE > $OUTPUT_FILE
1133a8c52ebaSWaiman Long}
1134a8c52ebaSWaiman Long
1135a8c52ebaSWaiman Long#
1136a8c52ebaSWaiman Long# Test if inotify events are properly generated when going into and out of
1137a8c52ebaSWaiman Long# invalid partition state.
1138a8c52ebaSWaiman Long#
1139a8c52ebaSWaiman Longtest_inotify()
1140a8c52ebaSWaiman Long{
1141a8c52ebaSWaiman Long	ERR=0
1142a8c52ebaSWaiman Long	PRS=/tmp/.prs_$$
1143105f3fe9SWaiman Long	cd $CGROUP2/test
1144a8c52ebaSWaiman Long	[[ -f $WAIT_INOTIFY ]] || {
1145a8c52ebaSWaiman Long		echo "wait_inotify not found, inotify test SKIPPED."
1146a8c52ebaSWaiman Long		return
1147a8c52ebaSWaiman Long	}
1148a8c52ebaSWaiman Long
1149a8c52ebaSWaiman Long	pause 0.01
1150a8c52ebaSWaiman Long	echo 1 > cpuset.cpus
1151a8c52ebaSWaiman Long	echo 0 > cgroup.procs
1152a8c52ebaSWaiman Long	echo root > cpuset.cpus.partition
1153a8c52ebaSWaiman Long	pause 0.01
1154a8c52ebaSWaiman Long	rm -f $PRS
1155a8c52ebaSWaiman Long	wait_inotify $PWD/cpuset.cpus.partition $PRS &
1156a8c52ebaSWaiman Long	pause 0.01
1157105f3fe9SWaiman Long	set_ctrl_state . "O1=0"
1158a8c52ebaSWaiman Long	pause 0.01
1159a8c52ebaSWaiman Long	check_cgroup_states ".:P-1"
1160a8c52ebaSWaiman Long	if [[ $? -ne 0 ]]
1161a8c52ebaSWaiman Long	then
1162a8c52ebaSWaiman Long		echo "FAILED: Inotify test - partition not invalid"
1163a8c52ebaSWaiman Long		ERR=1
1164a8c52ebaSWaiman Long	elif [[ ! -f $PRS ]]
1165a8c52ebaSWaiman Long	then
1166a8c52ebaSWaiman Long		echo "FAILED: Inotify test - event not generated"
1167a8c52ebaSWaiman Long		ERR=1
1168a8c52ebaSWaiman Long		kill %1
1169a8c52ebaSWaiman Long	elif [[ $(cat $PRS) != "root invalid"* ]]
1170a8c52ebaSWaiman Long	then
1171a8c52ebaSWaiman Long		echo "FAILED: Inotify test - incorrect state"
1172a8c52ebaSWaiman Long		cat $PRS
1173a8c52ebaSWaiman Long		ERR=1
1174a8c52ebaSWaiman Long	fi
1175a8c52ebaSWaiman Long	online_cpus
1176a8c52ebaSWaiman Long	echo member > cpuset.cpus.partition
1177a8c52ebaSWaiman Long	echo 0 > ../cgroup.procs
1178a8c52ebaSWaiman Long	if [[ $ERR -ne 0 ]]
1179a8c52ebaSWaiman Long	then
1180a8c52ebaSWaiman Long		exit 1
1181a8c52ebaSWaiman Long	else
1182a8c52ebaSWaiman Long		echo "Inotify test PASSED"
1183a8c52ebaSWaiman Long	fi
1184b2b2b4d0SWaiman Long	echo member > cpuset.cpus.partition
1185b2b2b4d0SWaiman Long	echo "" > cpuset.cpus
1186a8c52ebaSWaiman Long}
1187a8c52ebaSWaiman Long
11881e85591dSKamalesh Babulaltrap cleanup 0 2 3 6
1189a8c52ebaSWaiman Longrun_state_test TEST_MATRIX
1190*e8a457b7SWaiman Longrun_remote_state_test REMOTE_TEST_MATRIX
1191a8c52ebaSWaiman Longtest_isolated
1192a8c52ebaSWaiman Longtest_inotify
1193a8c52ebaSWaiman Longecho "All tests PASSED."
1194