xref: /linux/tools/testing/selftests/cgroup/test_cpuset_prs.sh (revision b2b2b4d058b776be0168b4ea46ed84cfb0f884e9)
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
91*b2b2b4d0SWaiman Long# the tests may fail incorrectly. Wait a bit and retry again just in case
92*b2b2b4d0SWaiman Long# these isolated CPUs are leftover from previous run and have just been
93*b2b2b4d0SWaiman Long# cleaned up earlier in this script.
94*b2b2b4d0SWaiman Long#
95*b2b2b4d0SWaiman Long# These pre-isolated CPUs should stay in an isolated state throughout the
96*b2b2b4d0SWaiman Long# testing process for now.
9743a17fcfSWaiman Long#
9843a17fcfSWaiman LongBOOT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
99*b2b2b4d0SWaiman Long[[ -n "$BOOT_ISOLCPUS" ]] && {
100*b2b2b4d0SWaiman Long	sleep 0.5
101*b2b2b4d0SWaiman Long	BOOT_ISOLCPUS=$(cat $CGROUP2/cpuset.cpus.isolated)
102*b2b2b4d0SWaiman 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
109*b2b2b4d0SWaiman Long
1101e85591dSKamalesh Babulalcleanup()
1111e85591dSKamalesh Babulal{
1121e85591dSKamalesh Babulal	online_cpus
113105f3fe9SWaiman Long	cd $CGROUP2
114*b2b2b4d0SWaiman Long	rmdir A1/A2/A3 A1/A2 A1 B1 test/A1 test/B1 test > /dev/null 2>&1
1151bf33285SWaiman Long	[[ -n "$SCHED_DEBUG" ]] &&
1161e85591dSKamalesh Babulal		echo "$SCHED_DEBUG" > /sys/kernel/debug/sched/verbose
1171e85591dSKamalesh Babulal}
1181e85591dSKamalesh Babulal
119a8c52ebaSWaiman Long# Pause in ms
120a8c52ebaSWaiman Longpause()
121a8c52ebaSWaiman Long{
122a8c52ebaSWaiman Long	DELAY=$1
123a8c52ebaSWaiman Long	LOOP=0
124a8c52ebaSWaiman Long	while [[ $LOOP -lt $DELAY_FACTOR ]]
125a8c52ebaSWaiman Long	do
126a8c52ebaSWaiman Long		sleep $DELAY
127a8c52ebaSWaiman Long		((LOOP++))
128a8c52ebaSWaiman Long	done
129a8c52ebaSWaiman Long	return 0
130a8c52ebaSWaiman Long}
131a8c52ebaSWaiman Long
132a8c52ebaSWaiman Longconsole_msg()
133a8c52ebaSWaiman Long{
134a8c52ebaSWaiman Long	MSG=$1
135a8c52ebaSWaiman Long	echo "$MSG"
13643ee4014SWaiman Long	echo "" > $CONSOLE
13743ee4014SWaiman Long	echo "$MSG" > $CONSOLE
138a8c52ebaSWaiman Long	pause 0.01
139a8c52ebaSWaiman Long}
140a8c52ebaSWaiman Long
141a8c52ebaSWaiman Longtest_partition()
142a8c52ebaSWaiman Long{
143a8c52ebaSWaiman Long	EXPECTED_VAL=$1
144a8c52ebaSWaiman Long	echo $EXPECTED_VAL > cpuset.cpus.partition
145a8c52ebaSWaiman Long	[[ $? -eq 0 ]] || exit 1
146a8c52ebaSWaiman Long	ACTUAL_VAL=$(cat cpuset.cpus.partition)
147a8c52ebaSWaiman Long	[[ $ACTUAL_VAL != $EXPECTED_VAL ]] && {
148105f3fe9SWaiman Long		echo "cpuset.cpus.partition: expect $EXPECTED_VAL, found $ACTUAL_VAL"
149a8c52ebaSWaiman Long		echo "Test FAILED"
150a8c52ebaSWaiman Long		exit 1
151a8c52ebaSWaiman Long	}
152a8c52ebaSWaiman Long}
153a8c52ebaSWaiman Long
154a8c52ebaSWaiman Longtest_effective_cpus()
155a8c52ebaSWaiman Long{
156a8c52ebaSWaiman Long	EXPECTED_VAL=$1
157a8c52ebaSWaiman Long	ACTUAL_VAL=$(cat cpuset.cpus.effective)
158a8c52ebaSWaiman Long	[[ "$ACTUAL_VAL" != "$EXPECTED_VAL" ]] && {
159105f3fe9SWaiman Long		echo "cpuset.cpus.effective: expect '$EXPECTED_VAL', found '$ACTUAL_VAL'"
160a8c52ebaSWaiman Long		echo "Test FAILED"
161a8c52ebaSWaiman Long		exit 1
162a8c52ebaSWaiman Long	}
163a8c52ebaSWaiman Long}
164a8c52ebaSWaiman Long
165a8c52ebaSWaiman Long# Adding current process to cgroup.procs as a test
166a8c52ebaSWaiman Longtest_add_proc()
167a8c52ebaSWaiman Long{
168a8c52ebaSWaiman Long	OUTSTR="$1"
169a8c52ebaSWaiman Long	ERRMSG=$((echo $$ > cgroup.procs) |& cat)
170a8c52ebaSWaiman Long	echo $ERRMSG | grep -q "$OUTSTR"
171a8c52ebaSWaiman Long	[[ $? -ne 0 ]] && {
172a8c52ebaSWaiman Long		echo "cgroup.procs: expect '$OUTSTR', got '$ERRMSG'"
173a8c52ebaSWaiman Long		echo "Test FAILED"
174a8c52ebaSWaiman Long		exit 1
175a8c52ebaSWaiman Long	}
176a8c52ebaSWaiman Long	echo $$ > $CGROUP2/cgroup.procs	# Move out the task
177a8c52ebaSWaiman Long}
178a8c52ebaSWaiman Long
179a8c52ebaSWaiman Long#
180a8c52ebaSWaiman Long# Cpuset controller state transition test matrix.
181a8c52ebaSWaiman Long#
182a8c52ebaSWaiman Long# Cgroup test hierarchy
183a8c52ebaSWaiman Long#
184*b2b2b4d0SWaiman Long#	      root
185*b2b2b4d0SWaiman Long#	        |
186*b2b2b4d0SWaiman Long#	 +------+------+
187*b2b2b4d0SWaiman Long#	 |             |
188*b2b2b4d0SWaiman Long#	 A1            B1
189*b2b2b4d0SWaiman Long#	 |
190*b2b2b4d0SWaiman Long#	 A2
191*b2b2b4d0SWaiman Long#	 |
192*b2b2b4d0SWaiman Long#	 A3
193a8c52ebaSWaiman Long#
194105f3fe9SWaiman Long#  P<v> = set cpus.partition (0:member, 1:root, 2:isolated)
19546c521baSWaiman Long#  C<l> = add cpu-list to cpuset.cpus
19646c521baSWaiman Long#  X<l> = add cpu-list to cpuset.cpus.exclusive
197a8c52ebaSWaiman Long#  S<p> = use prefix in subtree_control
198a8c52ebaSWaiman Long#  T    = put a task into cgroup
199*b2b2b4d0SWaiman Long#  CX<l> = add cpu-list to both cpuset.cpus and cpuset.cpus.exclusive
200105f3fe9SWaiman Long#  O<c>=<v> = Write <v> to CPU online file of <c>
201a8c52ebaSWaiman Long#
2021c0be3f7SWaiman Long# ECPUs    - effective CPUs of cpusets
2031c0be3f7SWaiman Long# Pstate   - partition root state
2041c0be3f7SWaiman Long# ISOLCPUS - isolated CPUs (<icpus>[,<icpus2>])
2051c0be3f7SWaiman Long#
2061c0be3f7SWaiman Long# Note that if there are 2 fields in ISOLCPUS, the first one is for
2071c0be3f7SWaiman Long# sched-debug matching which includes offline CPUs and single-CPU partitions
2081c0be3f7SWaiman Long# while the second one is for matching cpuset.cpus.isolated.
2091c0be3f7SWaiman Long#
210a8c52ebaSWaiman LongSETUP_A123_PARTITIONS="C1-3:P1:S+ C2-3:P1:S+ C3:P1"
211a8c52ebaSWaiman LongTEST_MATRIX=(
212105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
213105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
214105f3fe9SWaiman Long	"   C0-1     .      .    C2-3    S+    C4-5     .      .     0 A2:0-1"
215105f3fe9SWaiman Long	"   C0-1     .      .    C2-3    P1      .      .      .     0 "
216105f3fe9SWaiman Long	"   C0-1     .      .    C2-3   P1:S+ C0-1:P1   .      .     0 "
217105f3fe9SWaiman Long	"   C0-1     .      .    C2-3   P1:S+  C1:P1    .      .     0 "
218105f3fe9SWaiman Long	"  C0-1:S+   .      .    C2-3     .      .      .     P1     0 "
219105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+     C1      .      .     0 "
220105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+    C1:P1    .      .     0 "
221105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+    C1:P1    .     P1     0 "
222105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3   C4-5     .      .      .     0 A1:4-5"
223105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3  S+:C4-5   .      .      .     0 A1:4-5"
224105f3fe9SWaiman Long	"   C0-1     .      .   C2-3:P1   .      .      .     C2     0 "
225105f3fe9SWaiman Long	"   C0-1     .      .   C2-3:P1   .      .      .    C4-5    0 B1:4-5"
22665046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .      .      .      .      .     0 A1:0-1|A2:2-3"
22765046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     C1-3    .      .      .     0 A1:1|A2:2-3"
22865046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     C3      .      .      .     0 A1:|A2:3 A1:P1|A2:P1"
22965046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     C3      P0     .      .     0 A1:3|A2:3 A1:P1|A2:P0"
23065046b5eSWaiman Long	"C2-3:P1:S+  C2:P1  .      .     C2-4    .      .      .     0 A1:3-4|A2:2"
23165046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     C3      .      .     C0-2   0 A1:|B1:0-2 A1:P1|A2:P1"
23265046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     C2-3    .      .      .     0 A1:|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
233a8c52ebaSWaiman Long
234a8c52ebaSWaiman Long	# CPU offlining cases:
23565046b5eSWaiman Long	"   C0-1     .      .    C2-3    S+    C4-5     .     O2=0   0 A1:0-1|B1:3"
23665046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O2=0    .      .      .     0 A1:0-1|A2:3"
23765046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O2=0   O2=1    .      .     0 A1:0-1|A2:2-3"
23865046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O1=0    .      .      .     0 A1:0|A2:2-3"
23965046b5eSWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O1=0   O1=1    .      .     0 A1:0-1|A2:2-3"
24065046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O3=0   O3=1    .      .     0 A1:2|A2:3 A1:P1|A2:P1"
24165046b5eSWaiman Long	"C2-3:P1:S+  C3:P2  .      .     O3=0   O3=1    .      .     0 A1:2|A2:3 A1:P1|A2:P2"
24265046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O2=0   O2=1    .      .     0 A1:2|A2:3 A1:P1|A2:P1"
24365046b5eSWaiman Long	"C2-3:P1:S+  C3:P2  .      .     O2=0   O2=1    .      .     0 A1:2|A2:3 A1:P1|A2:P2"
24465046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O2=0    .      .      .     0 A1:|A2:3 A1:P1|A2:P1"
24565046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O3=0    .      .      .     0 A1:2|A2: A1:P1|A2:P1"
24665046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .    T:O2=0   .      .      .     0 A1:3|A2:3 A1:P1|A2:P-1"
24765046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .      .    T:O3=0   .      .     0 A1:2|A2:2 A1:P1|A2:P-1"
24865046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     O1=0    .      .      .     0 A1:|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
24965046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     O2=0    .      .      .     0 A1:1|A2:|A3:3 A1:P1|A2:P1|A3:P1"
25065046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     O3=0    .      .      .     0 A1:1|A2:2|A3: A1:P1|A2:P1|A3:P1"
25165046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0   .      .      .     0 A1:2-3|A2:2-3|A3:3 A1:P1|A2:P-1|A3:P-1"
25265046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .      .    T:O2=0   .      .     0 A1:1|A2:3|A3:3 A1:P1|A2:P1|A3:P-1"
25365046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .      .      .    T:O3=0   .     0 A1:1|A2:2|A3:2 A1:P1|A2:P1|A3:P-1"
25465046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0  O1=1    .      .     0 A1:1|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
25565046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .      .    T:O2=0  O2=1    .     0 A1:1|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
25665046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .      .      .    T:O3=0  O3=1   0 A1:1|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
25765046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0  O2=0   O1=1    .     0 A1:1|A2:|A3:3 A1:P1|A2:P1|A3:P1"
25865046b5eSWaiman 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"
259a8c52ebaSWaiman Long
260105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
261105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
262105f3fe9SWaiman Long	#
263105f3fe9SWaiman Long	# Remote partition and cpuset.cpus.exclusive tests
264105f3fe9SWaiman Long	#
26565046b5eSWaiman Long	" C0-3:S+ C1-3:S+ C2-3     .    X2-3     .      .      .     0 A1:0-3|A2:1-3|A3:2-3|XA1:2-3"
26665046b5eSWaiman 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"
26765046b5eSWaiman 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"
26865046b5eSWaiman 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"
26965046b5eSWaiman 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"
27065046b5eSWaiman 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"
271105f3fe9SWaiman Long	" C0-3:S+ C1-3:S+ C2-3   C4-5     .      .      .      P2    0 B1:4-5 B1:P2 4-5"
27265046b5eSWaiman 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"
27365046b5eSWaiman 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"
27465046b5eSWaiman 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"
27565046b5eSWaiman 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"
27665046b5eSWaiman Long	" C4:X0-3:S+ X1-3:S+ X2-3  .      .      P2     .      .     0 A1:4|A2:1-3|A3:1-3 A2:P2 1-3"
27765046b5eSWaiman Long	" C4:X0-3:S+ X1-3:S+ X2-3  .      .      .      P2     .     0 A1:4|A2:4|A3:2-3 A3:P2 2-3"
278105f3fe9SWaiman Long
279105f3fe9SWaiman Long	# Nested remote/local partition tests
28065046b5eSWaiman 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 \
28165046b5eSWaiman Long								       A1:P0|A2:P1|A3:P2|B1:P1 2-3"
28265046b5eSWaiman 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 \
28365046b5eSWaiman Long								       A1:P0|A2:P1|A3:P2|B1:P1 2-4|2-3"
28465046b5eSWaiman 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 \
28565046b5eSWaiman Long								       A1:P0|A2:P1|A3:P0|B1:P1"
28665046b5eSWaiman 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 \
28765046b5eSWaiman Long								       A1:P0|A2:P1|A3:P2|B1:P1 2-4|3"
28865046b5eSWaiman 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 \
28965046b5eSWaiman Long								       A1:P0|A2:P2|A3:P1 2-4|2-3"
29065046b5eSWaiman 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 \
29165046b5eSWaiman Long								       A1:P0|A2:P2|A3:P1 2"
292105f3fe9SWaiman Long	" C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \
29365046b5eSWaiman Long				   .      .      X5      .      .    0 A1:0-4|A2:1-4|A3:2-4 \
29465046b5eSWaiman Long								       A1:P0|A2:P-2|A3:P-1"
295105f3fe9SWaiman Long	" C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \
29665046b5eSWaiman Long				   .      .      .      X1      .    0 A1:0-1|A2:2-4|A3:2-4 \
29765046b5eSWaiman Long								       A1:P0|A2:P2|A3:P-1 2-4"
298105f3fe9SWaiman Long
299105f3fe9SWaiman Long	# Remote partition offline tests
30065046b5eSWaiman 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"
30165046b5eSWaiman 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"
30265046b5eSWaiman 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"
30365046b5eSWaiman 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|"
304105f3fe9SWaiman Long
305105f3fe9SWaiman Long	# An invalidated remote partition cannot self-recover from hotplug
30665046b5eSWaiman 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"
307105f3fe9SWaiman Long
308105f3fe9SWaiman Long	# cpus.exclusive.effective clearing test
30965046b5eSWaiman Long	" C0-3:S+ C1-3:S+  C2      .   X2-3:X    .      .      .     0 A1:0-3|A2:1-3|A3:2|XA1:"
310105f3fe9SWaiman Long
31146c521baSWaiman Long	# Invalid to valid remote partition transition test
31265046b5eSWaiman Long	" C0-3:S+   C1-3    .      .      .    X3:P2    .      .     0 A1:0-3|A2:1-3|XA2: A2:P-2"
313105f3fe9SWaiman Long	" C0-3:S+ C1-3:X3:P2
31465046b5eSWaiman Long			    .      .    X2-3    P2      .      .     0 A1:0-2|A2:3|XA2:3 A2:P2 3"
315105f3fe9SWaiman Long
316105f3fe9SWaiman Long	# Invalid to valid local partition direct transition tests
31765046b5eSWaiman 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"
31865046b5eSWaiman 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"
31965046b5eSWaiman Long	"  C0-3:P2   .      .    C4-6   C0-4     .      .      .     0 A1:0-4|B1:4-6 A1:P-2|B1:P0"
32065046b5eSWaiman Long	"  C0-3:P2   .      .    C4-6 C0-4:C0-3  .      .      .     0 A1:0-3|B1:4-6 A1:P2|B1:P0 0-3"
32165046b5eSWaiman Long	"  C0-3:P2   .      .  C3-5:C4-5  .      .      .      .     0 A1:0-3|B1:4-5 A1:P2|B1:P0 0-3"
322105f3fe9SWaiman Long
323105f3fe9SWaiman Long	# Local partition invalidation tests
324105f3fe9SWaiman Long	" C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \
32565046b5eSWaiman Long				   .      .      .      .      .     0 A1:1|A2:2|A3:3 A1:P2|A2:P2|A3:P2 1-3"
326105f3fe9SWaiman Long	" C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \
32765046b5eSWaiman Long				   .      .     X4      .      .     0 A1:1-3|A2:1-3|A3:2-3|XA2:|XA3: A1:P2|A2:P-2|A3:P-2 1-3"
328105f3fe9SWaiman Long	" C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \
32965046b5eSWaiman 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"
33046c521baSWaiman Long	# Local partition CPU change tests
33165046b5eSWaiman Long	" C0-5:S+:P2 C4-5:S+:P1 .  .      .    C3-5     .      .     0 A1:0-2|A2:3-5 A1:P2|A2:P1 0-2"
33265046b5eSWaiman Long	" C0-5:S+:P2 C4-5:S+:P1 .  .    C1-5     .      .      .     0 A1:1-3|A2:4-5 A1:P2|A2:P1 1-3"
333105f3fe9SWaiman Long
334105f3fe9SWaiman Long	# cpus_allowed/exclusive_cpus update tests
335105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \
33665046b5eSWaiman Long				   .    X:C4     .      P2     .     0 A1:4|A2:4|XA2:|XA3:|A3:4 \
33765046b5eSWaiman Long								       A1:P0|A3:P-2"
338105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \
33965046b5eSWaiman Long				   .     X1      .      P2     .     0 A1:0-3|A2:1-3|XA1:1|XA2:|XA3:|A3:2-3 \
34065046b5eSWaiman Long								       A1:P0|A3:P-2"
341105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \
34265046b5eSWaiman Long				   .      .     X3      P2     .     0 A1:0-2|A2:1-2|XA2:3|XA3:3|A3:3 \
34365046b5eSWaiman Long								       A1:P0|A3:P2 3"
344105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \
34565046b5eSWaiman Long				   .      .     X3      .      .     0 A1:0-2|A2:1-2|XA2:3|XA3:3|A3:3|XA3:3 \
34665046b5eSWaiman Long								       A1:P0|A3:P2 3"
347105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \
34865046b5eSWaiman Long				   .     X4      .      .      .     0 A1:0-3|A2:1-3|A3:2-3|XA1:4|XA2:|XA3 \
34965046b5eSWaiman Long								       A1:P0|A3:P-2"
350105f3fe9SWaiman Long
351105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
352105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
353a8c52ebaSWaiman Long	#
35492841d6eSWaiman Long	# Incorrect change to cpuset.cpus[.exclusive] invalidates partition root
355a8c52ebaSWaiman Long	#
356a8c52ebaSWaiman Long	# Adding CPUs to partition root that are not in parent's
357a8c52ebaSWaiman Long	# cpuset.cpus is allowed, but those extra CPUs are ignored.
35865046b5eSWaiman Long	"C2-3:P1:S+ C3:P1   .      .      .     C2-4    .      .     0 A1:|A2:2-3 A1:P1|A2:P1"
359a8c52ebaSWaiman Long
360a8c52ebaSWaiman Long	# Taking away all CPUs from parent or itself if there are tasks
361a8c52ebaSWaiman Long	# will make the partition invalid.
36265046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .      T     C2-3    .      .     0 A1:2-3|A2:2-3 A1:P1|A2:P-1"
36365046b5eSWaiman Long	" C3:P1:S+    C3    .      .      T      P1     .      .     0 A1:3|A2:3 A1:P1|A2:P-1"
36465046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .    T:C2-3   .      .      .     0 A1:2-3|A2:2-3|A3:3 A1:P1|A2:P-1|A3:P-1"
36565046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    . T:C2-3:C1-3 .      .      .     0 A1:1|A2:2|A3:3 A1:P1|A2:P1|A3:P1"
366a8c52ebaSWaiman Long
367a8c52ebaSWaiman Long	# Changing a partition root to member makes child partitions invalid
36865046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .      P0     .      .      .     0 A1:2-3|A2:3 A1:P0|A2:P-1"
36965046b5eSWaiman Long	"$SETUP_A123_PARTITIONS    .     C2-3    P0     .      .     0 A1:2-3|A2:2-3|A3:3 A1:P1|A2:P0|A3:P-1"
370a8c52ebaSWaiman Long
371a8c52ebaSWaiman Long	# cpuset.cpus can contains cpus not in parent's cpuset.cpus as long
372a8c52ebaSWaiman Long	# as they overlap.
37365046b5eSWaiman Long	"C2-3:P1:S+  .      .      .      .   C3-4:P1   .      .     0 A1:2|A2:3 A1:P1|A2:P1"
374a8c52ebaSWaiman Long
375a8c52ebaSWaiman Long	# Deletion of CPUs distributed to child cgroup is allowed.
37665046b5eSWaiman Long	"C0-1:P1:S+ C1      .    C2-3   C4-5     .      .      .     0 A1:4-5|A2:4-5"
377a8c52ebaSWaiman Long
378a8c52ebaSWaiman Long	# To become a valid partition root, cpuset.cpus must overlap parent's
379a8c52ebaSWaiman Long	# cpuset.cpus.
38065046b5eSWaiman Long	"  C0-1:P1   .      .    C2-3    S+   C4-5:P1   .      .     0 A1:0-1|A2:0-1 A1:P1|A2:P-1"
381a8c52ebaSWaiman Long
382a8c52ebaSWaiman Long	# Enabling partition with child cpusets is allowed
38365046b5eSWaiman Long	"  C0-1:S+  C1      .    C2-3    P1      .      .      .     0 A1:0-1|A2:1 A1:P1"
384a8c52ebaSWaiman Long
38565046b5eSWaiman Long	# A partition root with non-partition root parent is invalid| but it
386a8c52ebaSWaiman Long	# can be made valid if its parent becomes a partition root too.
38765046b5eSWaiman Long	"  C0-1:S+  C1      .    C2-3     .      P2     .      .     0 A1:0-1|A2:1 A1:P0|A2:P-2"
38865046b5eSWaiman Long	"  C0-1:S+ C1:P2    .    C2-3     P1     .      .      .     0 A1:0|A2:1 A1:P1|A2:P2"
389a8c52ebaSWaiman Long
390a8c52ebaSWaiman Long	# A non-exclusive cpuset.cpus change will invalidate partition and its siblings
39165046b5eSWaiman Long	"  C0-1:P1   .      .    C2-3   C0-2     .      .      .     0 A1:0-2|B1:2-3 A1:P-1|B1:P0"
39265046b5eSWaiman Long	"  C0-1:P1   .      .  P1:C2-3  C0-2     .      .      .     0 A1:0-2|B1:2-3 A1:P-1|B1:P-1"
39365046b5eSWaiman Long	"   C0-1     .      .  P1:C2-3  C0-2     .      .      .     0 A1:0-2|B1:2-3 A1:P0|B1:P-1"
394a8c52ebaSWaiman Long
3951c0be3f7SWaiman Long	# cpuset.cpus can overlap with sibling cpuset.cpus.exclusive but not subsumed by it
39665046b5eSWaiman Long	"   C0-3     .      .    C4-5     X5     .      .      .     0 A1:0-3|B1:4-5"
3971c0be3f7SWaiman Long
39892841d6eSWaiman Long	# Child partition root that try to take all CPUs from parent partition
39992841d6eSWaiman Long	# with tasks will remain invalid.
40065046b5eSWaiman Long	" C1-4:P1:S+ P1     .      .       .     .      .      .     0 A1:1-4|A2:1-4 A1:P1|A2:P-1"
40165046b5eSWaiman Long	" C1-4:P1:S+ P1     .      .       .   C1-4     .      .     0 A1|A2:1-4 A1:P1|A2:P1"
40265046b5eSWaiman Long	" C1-4:P1:S+ P1     .      .       T   C1-4     .      .     0 A1:1-4|A2:1-4 A1:P1|A2:P-1"
40392841d6eSWaiman Long
40492841d6eSWaiman Long	# Clearing of cpuset.cpus with a preset cpuset.cpus.exclusive shouldn't
40592841d6eSWaiman Long	# affect cpuset.cpus.exclusive.effective.
40665046b5eSWaiman Long	" C1-4:X3:S+ C1:X3  .      .       .     C      .      .     0 A2:1-4|XA2:3"
40792841d6eSWaiman Long
408105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
409105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
410a8c52ebaSWaiman Long	# Failure cases:
411a8c52ebaSWaiman Long
412a8c52ebaSWaiman Long	# A task cannot be added to a partition with no cpu
41365046b5eSWaiman Long	"C2-3:P1:S+  C3:P1  .      .    O2=0:T   .      .      .     1 A1:|A2:3 A1:P1|A2:P1"
414105f3fe9SWaiman Long
415105f3fe9SWaiman Long	# Changes to cpuset.cpus.exclusive that violate exclusivity rule is rejected
41665046b5eSWaiman Long	"   C0-3     .      .    C4-5   X0-3     .      .     X3-5   1 A1:0-3|B1:4-5"
4171c0be3f7SWaiman Long
4181c0be3f7SWaiman Long	# cpuset.cpus cannot be a subset of sibling cpuset.cpus.exclusive
41965046b5eSWaiman Long	"   C0-3     .      .    C4-5   X3-5     .      .      .     1 A1:0-3|B1:4-5"
420a8c52ebaSWaiman Long)
421a8c52ebaSWaiman Long
422a8c52ebaSWaiman Long#
423a8c52ebaSWaiman Long# Write to the cpu online file
424105f3fe9SWaiman Long#  $1 - <c>=<v> where <c> = cpu number, <v> value to be written
425a8c52ebaSWaiman Long#
426a8c52ebaSWaiman Longwrite_cpu_online()
427a8c52ebaSWaiman Long{
428105f3fe9SWaiman Long	CPU=${1%=*}
429105f3fe9SWaiman Long	VAL=${1#*=}
430a8c52ebaSWaiman Long	CPUFILE=//sys/devices/system/cpu/cpu${CPU}/online
431a8c52ebaSWaiman Long	if [[ $VAL -eq 0 ]]
432a8c52ebaSWaiman Long	then
433a8c52ebaSWaiman Long		OFFLINE_CPUS="$OFFLINE_CPUS $CPU"
434a8c52ebaSWaiman Long	else
435a8c52ebaSWaiman Long		[[ -n "$OFFLINE_CPUS" ]] && {
436a8c52ebaSWaiman Long			OFFLINE_CPUS=$(echo $CPU $CPU $OFFLINE_CPUS | fmt -1 |\
437a8c52ebaSWaiman Long					sort | uniq -u)
438a8c52ebaSWaiman Long		}
439a8c52ebaSWaiman Long	fi
440a8c52ebaSWaiman Long	echo $VAL > $CPUFILE
44172c6303aSWaiman Long	pause 0.05
442a8c52ebaSWaiman Long}
443a8c52ebaSWaiman Long
444a8c52ebaSWaiman Long#
445a8c52ebaSWaiman Long# Set controller state
446a8c52ebaSWaiman Long#  $1 - cgroup directory
447a8c52ebaSWaiman Long#  $2 - state
448a8c52ebaSWaiman Long#  $3 - showerr
449a8c52ebaSWaiman Long#
450a8c52ebaSWaiman Long# The presence of ":" in state means transition from one to the next.
451a8c52ebaSWaiman Long#
452a8c52ebaSWaiman Longset_ctrl_state()
453a8c52ebaSWaiman Long{
454a8c52ebaSWaiman Long	TMPMSG=/tmp/.msg_$$
455a8c52ebaSWaiman Long	CGRP=$1
456a8c52ebaSWaiman Long	STATE=$2
457105f3fe9SWaiman Long	SHOWERR=${3}
458a8c52ebaSWaiman Long	CTRL=${CTRL:=$CONTROLLER}
459a8c52ebaSWaiman Long	HASERR=0
460a8c52ebaSWaiman Long	REDIRECT="2> $TMPMSG"
461a8c52ebaSWaiman Long	[[ -z "$STATE" || "$STATE" = '.' ]] && return 0
462105f3fe9SWaiman Long	[[ $VERBOSE -gt 0 ]] && SHOWERR=1
463a8c52ebaSWaiman Long
464a8c52ebaSWaiman Long	rm -f $TMPMSG
465a8c52ebaSWaiman Long	for CMD in $(echo $STATE | sed -e "s/:/ /g")
466a8c52ebaSWaiman Long	do
467a8c52ebaSWaiman Long		TFILE=$CGRP/cgroup.procs
468a8c52ebaSWaiman Long		SFILE=$CGRP/cgroup.subtree_control
469a8c52ebaSWaiman Long		PFILE=$CGRP/cpuset.cpus.partition
470a8c52ebaSWaiman Long		CFILE=$CGRP/cpuset.cpus
471105f3fe9SWaiman Long		XFILE=$CGRP/cpuset.cpus.exclusive
472*b2b2b4d0SWaiman Long		case $CMD in
473*b2b2b4d0SWaiman Long		    S*) PREFIX=${CMD#?}
474a8c52ebaSWaiman Long			COMM="echo ${PREFIX}${CTRL} > $SFILE"
475a8c52ebaSWaiman Long			eval $COMM $REDIRECT
476*b2b2b4d0SWaiman Long			;;
477*b2b2b4d0SWaiman Long		    X*)
478105f3fe9SWaiman Long			CPUS=${CMD#?}
479105f3fe9SWaiman Long			COMM="echo $CPUS > $XFILE"
480105f3fe9SWaiman Long			eval $COMM $REDIRECT
481*b2b2b4d0SWaiman Long			;;
482*b2b2b4d0SWaiman Long		    CX*)
483*b2b2b4d0SWaiman Long			CPUS=${CMD#??}
484*b2b2b4d0SWaiman Long			COMM="echo $CPUS > $CFILE; echo $CPUS > $XFILE"
485*b2b2b4d0SWaiman Long			eval $COMM $REDIRECT
486*b2b2b4d0SWaiman Long			;;
487*b2b2b4d0SWaiman Long		    C*) CPUS=${CMD#?}
488a8c52ebaSWaiman Long			COMM="echo $CPUS > $CFILE"
489a8c52ebaSWaiman Long			eval $COMM $REDIRECT
490*b2b2b4d0SWaiman Long			;;
491*b2b2b4d0SWaiman Long		    P*) VAL=${CMD#?}
492a8c52ebaSWaiman Long			case $VAL in
493a8c52ebaSWaiman Long			0)  VAL=member
494a8c52ebaSWaiman Long			    ;;
495a8c52ebaSWaiman Long			1)  VAL=root
496a8c52ebaSWaiman Long			    ;;
497a8c52ebaSWaiman Long			2)  VAL=isolated
498a8c52ebaSWaiman Long			    ;;
499a8c52ebaSWaiman Long			*)
500a8c52ebaSWaiman Long			    echo "Invalid partition state - $VAL"
501a8c52ebaSWaiman Long			    exit 1
502a8c52ebaSWaiman Long			    ;;
503a8c52ebaSWaiman Long			esac
504a8c52ebaSWaiman Long			COMM="echo $VAL > $PFILE"
505a8c52ebaSWaiman Long			eval $COMM $REDIRECT
506*b2b2b4d0SWaiman Long			;;
507*b2b2b4d0SWaiman Long		    O*) VAL=${CMD#?}
508a8c52ebaSWaiman Long			write_cpu_online $VAL
509*b2b2b4d0SWaiman Long			;;
510*b2b2b4d0SWaiman Long		    T*) COMM="echo 0 > $TFILE"
511a8c52ebaSWaiman Long			eval $COMM $REDIRECT
512*b2b2b4d0SWaiman Long			;;
513*b2b2b4d0SWaiman Long		    *)  echo "Unknown command: $CMD"
514*b2b2b4d0SWaiman Long		        exit 1
515*b2b2b4d0SWaiman Long			;;
516*b2b2b4d0SWaiman Long		esac
517a8c52ebaSWaiman Long		RET=$?
518a8c52ebaSWaiman Long		[[ $RET -ne 0 ]] && {
519a8c52ebaSWaiman Long			[[ -n "$SHOWERR" ]] && {
520a8c52ebaSWaiman Long				echo "$COMM"
521a8c52ebaSWaiman Long				cat $TMPMSG
522a8c52ebaSWaiman Long			}
523a8c52ebaSWaiman Long			HASERR=1
524a8c52ebaSWaiman Long		}
525a8c52ebaSWaiman Long		pause 0.01
526a8c52ebaSWaiman Long		rm -f $TMPMSG
527a8c52ebaSWaiman Long	done
528a8c52ebaSWaiman Long	return $HASERR
529a8c52ebaSWaiman Long}
530a8c52ebaSWaiman Long
531a8c52ebaSWaiman Longset_ctrl_state_noerr()
532a8c52ebaSWaiman Long{
533a8c52ebaSWaiman Long	CGRP=$1
534a8c52ebaSWaiman Long	STATE=$2
535a8c52ebaSWaiman Long	[[ -d $CGRP ]] || mkdir $CGRP
536a8c52ebaSWaiman Long	set_ctrl_state $CGRP $STATE 1
537a8c52ebaSWaiman Long	[[ $? -ne 0 ]] && {
538a8c52ebaSWaiman Long		echo "ERROR: Failed to set $2 to cgroup $1!"
539a8c52ebaSWaiman Long		exit 1
540a8c52ebaSWaiman Long	}
541a8c52ebaSWaiman Long}
542a8c52ebaSWaiman Long
543a8c52ebaSWaiman Longonline_cpus()
544a8c52ebaSWaiman Long{
545a8c52ebaSWaiman Long	[[ -n "OFFLINE_CPUS" ]] && {
546a8c52ebaSWaiman Long		for C in $OFFLINE_CPUS
547a8c52ebaSWaiman Long		do
548105f3fe9SWaiman Long			write_cpu_online ${C}=1
549a8c52ebaSWaiman Long		done
550a8c52ebaSWaiman Long	}
551a8c52ebaSWaiman Long}
552a8c52ebaSWaiman Long
553a8c52ebaSWaiman Long#
554*b2b2b4d0SWaiman Long# Remove all the test cgroup directories
555a8c52ebaSWaiman Long#
556a8c52ebaSWaiman Longreset_cgroup_states()
557a8c52ebaSWaiman Long{
558a8c52ebaSWaiman Long	echo 0 > $CGROUP2/cgroup.procs
559a8c52ebaSWaiman Long	online_cpus
560*b2b2b4d0SWaiman Long	rmdir $RESET_LIST > /dev/null 2>&1
561a8c52ebaSWaiman Long}
562a8c52ebaSWaiman Long
563a8c52ebaSWaiman Longdump_states()
564a8c52ebaSWaiman Long{
565*b2b2b4d0SWaiman Long	for DIR in $CGROUP_LIST
566a8c52ebaSWaiman Long	do
567105f3fe9SWaiman Long		CPUS=$DIR/cpuset.cpus
568a8c52ebaSWaiman Long		ECPUS=$DIR/cpuset.cpus.effective
569105f3fe9SWaiman Long		XCPUS=$DIR/cpuset.cpus.exclusive
570105f3fe9SWaiman Long		XECPUS=$DIR/cpuset.cpus.exclusive.effective
571a8c52ebaSWaiman Long		PRS=$DIR/cpuset.cpus.partition
572105f3fe9SWaiman Long		PCPUS=$DIR/.__DEBUG__.cpuset.cpus.subpartitions
573877c737dSWaiman Long		ISCPUS=$DIR/cpuset.cpus.isolated
574105f3fe9SWaiman Long		[[ -e $CPUS   ]] && echo "$CPUS: $(cat $CPUS)"
575105f3fe9SWaiman Long		[[ -e $XCPUS  ]] && echo "$XCPUS: $(cat $XCPUS)"
576a8c52ebaSWaiman Long		[[ -e $ECPUS  ]] && echo "$ECPUS: $(cat $ECPUS)"
577105f3fe9SWaiman Long		[[ -e $XECPUS ]] && echo "$XECPUS: $(cat $XECPUS)"
578a8c52ebaSWaiman Long		[[ -e $PRS    ]] && echo "$PRS: $(cat $PRS)"
579105f3fe9SWaiman Long		[[ -e $PCPUS  ]] && echo "$PCPUS: $(cat $PCPUS)"
58072c6303aSWaiman Long		[[ -e $ISCPUS ]] && echo "$ISCPUS: $(cat $ISCPUS)"
581a8c52ebaSWaiman Long	done
582a8c52ebaSWaiman Long}
583a8c52ebaSWaiman Long
584a8c52ebaSWaiman Long#
585*b2b2b4d0SWaiman Long# Set the actual cgroup directory into $CGRP_DIR
586*b2b2b4d0SWaiman Long# $1 - cgroup name
587*b2b2b4d0SWaiman Long#
588*b2b2b4d0SWaiman Longset_cgroup_dir()
589*b2b2b4d0SWaiman Long{
590*b2b2b4d0SWaiman Long	CGRP_DIR=$1
591*b2b2b4d0SWaiman Long	[[ $CGRP_DIR = A2  ]] && CGRP_DIR=A1/A2
592*b2b2b4d0SWaiman Long	[[ $CGRP_DIR = A3  ]] && CGRP_DIR=A1/A2/A3
593*b2b2b4d0SWaiman Long	[[ $CGRP_DIR = c11 ]] && CGRP_DIR=p1/c11
594*b2b2b4d0SWaiman Long	[[ $CGRP_DIR = c12 ]] && CGRP_DIR=p1/c12
595*b2b2b4d0SWaiman Long	[[ $CGRP_DIR = c21 ]] && CGRP_DIR=p2/c21
596*b2b2b4d0SWaiman Long	[[ $CGRP_DIR = c22 ]] && CGRP_DIR=p2/c22
597*b2b2b4d0SWaiman Long}
598*b2b2b4d0SWaiman Long
599*b2b2b4d0SWaiman Long#
600a8c52ebaSWaiman Long# Check effective cpus
60165046b5eSWaiman Long# $1 - check string, format: <cgroup>:<cpu-list>[|<cgroup>:<cpu-list>]*
602a8c52ebaSWaiman Long#
603a8c52ebaSWaiman Longcheck_effective_cpus()
604a8c52ebaSWaiman Long{
605a8c52ebaSWaiman Long	CHK_STR=$1
60665046b5eSWaiman Long	for CHK in $(echo $CHK_STR | sed -e "s/|/ /g")
607a8c52ebaSWaiman Long	do
608a8c52ebaSWaiman Long		set -- $(echo $CHK | sed -e "s/:/ /g")
609a8c52ebaSWaiman Long		CGRP=$1
610*b2b2b4d0SWaiman Long		EXPECTED_CPUS=$2
611*b2b2b4d0SWaiman Long		ACTUAL_CPUS=
612105f3fe9SWaiman Long		if [[ $CGRP = X* ]]
613105f3fe9SWaiman Long		then
614105f3fe9SWaiman Long			CGRP=${CGRP#X}
615105f3fe9SWaiman Long			FILE=cpuset.cpus.exclusive.effective
616105f3fe9SWaiman Long		else
617105f3fe9SWaiman Long			FILE=cpuset.cpus.effective
618105f3fe9SWaiman Long		fi
619*b2b2b4d0SWaiman Long		set_cgroup_dir $CGRP
620*b2b2b4d0SWaiman Long		[[ -e $CGRP_DIR/$FILE ]] || return 1
621*b2b2b4d0SWaiman Long		ACTUAL_CPUS=$(cat $CGRP_DIR/$FILE)
622*b2b2b4d0SWaiman Long		[[ $EXPECTED_CPUS = $ACTUAL_CPUS ]] || return 1
623a8c52ebaSWaiman Long	done
624a8c52ebaSWaiman Long}
625a8c52ebaSWaiman Long
626a8c52ebaSWaiman Long#
627a8c52ebaSWaiman Long# Check cgroup states
62865046b5eSWaiman Long#  $1 - check string, format: <cgroup>:<state>[|<cgroup>:<state>]*
629a8c52ebaSWaiman Long#
630a8c52ebaSWaiman Longcheck_cgroup_states()
631a8c52ebaSWaiman Long{
632a8c52ebaSWaiman Long	CHK_STR=$1
63365046b5eSWaiman Long	for CHK in $(echo $CHK_STR | sed -e "s/|/ /g")
634a8c52ebaSWaiman Long	do
635a8c52ebaSWaiman Long		set -- $(echo $CHK | sed -e "s/:/ /g")
636a8c52ebaSWaiman Long		CGRP=$1
637*b2b2b4d0SWaiman Long		EXPECTED_STATE=$2
638a8c52ebaSWaiman Long		FILE=
639*b2b2b4d0SWaiman Long		EVAL=$(expr substr $EXPECTED_STATE 2 2)
640a8c52ebaSWaiman Long
641*b2b2b4d0SWaiman Long		set_cgroup_dir $CGRP
642*b2b2b4d0SWaiman Long		case $EXPECTED_STATE in
6431c0be3f7SWaiman Long			P*) FILE=$CGRP_DIR/cpuset.cpus.partition
644a8c52ebaSWaiman Long			    ;;
645*b2b2b4d0SWaiman Long			*)  echo "Unknown state: $EXPECTED_STATE!"
646a8c52ebaSWaiman Long			    exit 1
647a8c52ebaSWaiman Long			    ;;
648a8c52ebaSWaiman Long		esac
649*b2b2b4d0SWaiman Long		ACTUAL_STATE=$(cat $FILE)
650a8c52ebaSWaiman Long
651*b2b2b4d0SWaiman Long		case "$ACTUAL_STATE" in
652a8c52ebaSWaiman Long			member) VAL=0
653a8c52ebaSWaiman Long				;;
654a8c52ebaSWaiman Long			root)	VAL=1
655a8c52ebaSWaiman Long				;;
656a8c52ebaSWaiman Long			isolated)
657a8c52ebaSWaiman Long				VAL=2
658a8c52ebaSWaiman Long				;;
659a8c52ebaSWaiman Long			"root invalid"*)
660a8c52ebaSWaiman Long				VAL=-1
661a8c52ebaSWaiman Long				;;
662a8c52ebaSWaiman Long			"isolated invalid"*)
663a8c52ebaSWaiman Long				VAL=-2
664a8c52ebaSWaiman Long				;;
665a8c52ebaSWaiman Long		esac
666a8c52ebaSWaiman Long		[[ $EVAL != $VAL ]] && return 1
6671c0be3f7SWaiman Long
6681c0be3f7SWaiman Long		#
6691c0be3f7SWaiman Long		# For root partition, dump sched-domains info to console if
6701c0be3f7SWaiman Long		# verbose mode set for manual comparison with sched debug info.
6711c0be3f7SWaiman Long		#
6721c0be3f7SWaiman Long		[[ $VAL -eq 1 && $VERBOSE -gt 0 ]] && {
6731c0be3f7SWaiman Long			DOMS=$(cat $CGRP_DIR/cpuset.cpus.effective)
6741c0be3f7SWaiman Long			[[ -n "$DOMS" ]] &&
675*b2b2b4d0SWaiman Long				echo " [$CGRP_DIR] sched-domain: $DOMS" > $CONSOLE
6761c0be3f7SWaiman Long		}
677a8c52ebaSWaiman Long	done
678a8c52ebaSWaiman Long	return 0
679a8c52ebaSWaiman Long}
680a8c52ebaSWaiman Long
681a8c52ebaSWaiman Long#
682105f3fe9SWaiman Long# Get isolated (including offline) CPUs by looking at
683877c737dSWaiman Long# /sys/kernel/debug/sched/domains and cpuset.cpus.isolated control file,
68472c6303aSWaiman Long# if available, and compare that with the expected value.
685105f3fe9SWaiman Long#
68672c6303aSWaiman Long# Note that isolated CPUs from the sched/domains context include offline
68772c6303aSWaiman Long# CPUs as well as CPUs in non-isolated 1-CPU partition. Those CPUs may
688877c737dSWaiman Long# not be included in the cpuset.cpus.isolated control file which contains
68943a17fcfSWaiman Long# only CPUs in isolated partitions as well as those that are isolated at
69043a17fcfSWaiman Long# boot time.
691105f3fe9SWaiman Long#
69272c6303aSWaiman Long# $1 - expected isolated cpu list(s) <isolcpus1>{,<isolcpus2>}
69372c6303aSWaiman Long# <isolcpus1> - expected sched/domains value
694877c737dSWaiman Long# <isolcpus2> - cpuset.cpus.isolated value = <isolcpus1> if not defined
695105f3fe9SWaiman Long#
696105f3fe9SWaiman Longcheck_isolcpus()
697105f3fe9SWaiman Long{
698*b2b2b4d0SWaiman Long	EXPECTED_ISOLCPUS=$1
699*b2b2b4d0SWaiman Long	ISCPUS=${CGROUP2}/cpuset.cpus.isolated
700*b2b2b4d0SWaiman Long	ISOLCPUS=$(cat $ISCPUS)
701105f3fe9SWaiman Long	LASTISOLCPU=
702105f3fe9SWaiman Long	SCHED_DOMAINS=/sys/kernel/debug/sched/domains
703*b2b2b4d0SWaiman Long	if [[ $EXPECTED_ISOLCPUS = . ]]
70472c6303aSWaiman Long	then
705*b2b2b4d0SWaiman Long		EXPECTED_ISOLCPUS=
706*b2b2b4d0SWaiman Long		EXPECTED_SDOMAIN=
707*b2b2b4d0SWaiman Long	elif [[ $(expr $EXPECTED_ISOLCPUS : ".*|.*") > 0 ]]
70872c6303aSWaiman Long	then
709*b2b2b4d0SWaiman Long		set -- $(echo $EXPECTED_ISOLCPUS | sed -e "s/|/ /g")
710*b2b2b4d0SWaiman Long		EXPECTED_ISOLCPUS=$2
711*b2b2b4d0SWaiman Long		EXPECTED_SDOMAIN=$1
71272c6303aSWaiman Long	else
713*b2b2b4d0SWaiman Long		EXPECTED_SDOMAIN=$EXPECTED_ISOLCPUS
71472c6303aSWaiman Long	fi
71572c6303aSWaiman Long
71672c6303aSWaiman Long	#
7179b496a8bSWaiman Long	# Appending pre-isolated CPUs
7189b496a8bSWaiman Long	# Even though CPU #8 isn't used for testing, it can't be pre-isolated
7199b496a8bSWaiman Long	# to make appending those CPUs easier.
7209b496a8bSWaiman Long	#
7219b496a8bSWaiman Long	[[ -n "$BOOT_ISOLCPUS" ]] && {
722*b2b2b4d0SWaiman Long		EXPECTED_ISOLCPUS=${EXPECTED_ISOLCPUS:+${EXPECTED_ISOLCPUS},}${BOOT_ISOLCPUS}
723*b2b2b4d0SWaiman Long		EXPECTED_SDOMAIN=${EXPECTED_SDOMAIN:+${EXPECTED_SDOMAIN},}${BOOT_ISOLCPUS}
7249b496a8bSWaiman Long	}
7259b496a8bSWaiman Long
7269b496a8bSWaiman Long	#
72743a17fcfSWaiman Long	# Check cpuset.cpus.isolated cpumask
72872c6303aSWaiman Long	#
729*b2b2b4d0SWaiman Long	[[ "$EXPECTED_ISOLCPUS" != "$ISOLCPUS" ]] && {
73072c6303aSWaiman Long		# Take a 50ms pause and try again
73172c6303aSWaiman Long		pause 0.05
73272c6303aSWaiman Long		ISOLCPUS=$(cat $ISCPUS)
73372c6303aSWaiman Long	}
734*b2b2b4d0SWaiman Long	[[ "$EXPECTED_ISOLCPUS" != "$ISOLCPUS" ]] && return 1
73572c6303aSWaiman Long	ISOLCPUS=
736*b2b2b4d0SWaiman Long	EXPECTED_ISOLCPUS=$EXPECTED_SDOMAIN
73772c6303aSWaiman Long
73872c6303aSWaiman Long	#
73972c6303aSWaiman Long	# Use the sched domain in debugfs to check isolated CPUs, if available
74072c6303aSWaiman Long	#
741105f3fe9SWaiman Long	[[ -d $SCHED_DOMAINS ]] || return 0
742105f3fe9SWaiman Long
743105f3fe9SWaiman Long	for ((CPU=0; CPU < $NR_CPUS; CPU++))
744105f3fe9SWaiman Long	do
745105f3fe9SWaiman Long		[[ -n "$(ls ${SCHED_DOMAINS}/cpu$CPU)" ]] && continue
746105f3fe9SWaiman Long
747105f3fe9SWaiman Long		if [[ -z "$LASTISOLCPU" ]]
748105f3fe9SWaiman Long		then
749105f3fe9SWaiman Long			ISOLCPUS=$CPU
750105f3fe9SWaiman Long			LASTISOLCPU=$CPU
751105f3fe9SWaiman Long		elif [[ "$LASTISOLCPU" -eq $((CPU - 1)) ]]
752105f3fe9SWaiman Long		then
753105f3fe9SWaiman Long			echo $ISOLCPUS | grep -q "\<$LASTISOLCPU\$"
754105f3fe9SWaiman Long			if [[ $? -eq 0 ]]
755105f3fe9SWaiman Long			then
756105f3fe9SWaiman Long				ISOLCPUS=${ISOLCPUS}-
757105f3fe9SWaiman Long			fi
758105f3fe9SWaiman Long			LASTISOLCPU=$CPU
759105f3fe9SWaiman Long		else
760105f3fe9SWaiman Long			if [[ $ISOLCPUS = *- ]]
761105f3fe9SWaiman Long			then
762105f3fe9SWaiman Long				ISOLCPUS=${ISOLCPUS}$LASTISOLCPU
763105f3fe9SWaiman Long			fi
764105f3fe9SWaiman Long			ISOLCPUS=${ISOLCPUS},$CPU
765105f3fe9SWaiman Long			LASTISOLCPU=$CPU
766105f3fe9SWaiman Long		fi
767105f3fe9SWaiman Long	done
768105f3fe9SWaiman Long	[[ "$ISOLCPUS" = *- ]] && ISOLCPUS=${ISOLCPUS}$LASTISOLCPU
76943a17fcfSWaiman Long
770*b2b2b4d0SWaiman Long	[[ "$EXPECTED_SDOMAIN" = "$ISOLCPUS" ]]
771105f3fe9SWaiman Long}
772105f3fe9SWaiman Long
773105f3fe9SWaiman Longtest_fail()
774105f3fe9SWaiman Long{
775105f3fe9SWaiman Long	TESTNUM=$1
776105f3fe9SWaiman Long	TESTTYPE=$2
777105f3fe9SWaiman Long	ADDINFO=$3
778105f3fe9SWaiman Long	echo "Test $TEST[$TESTNUM] failed $TESTTYPE check!"
779105f3fe9SWaiman Long	[[ -n "$ADDINFO" ]] && echo "*** $ADDINFO ***"
780105f3fe9SWaiman Long	eval echo \${$TEST[$I]}
781105f3fe9SWaiman Long	echo
782105f3fe9SWaiman Long	dump_states
783105f3fe9SWaiman Long	exit 1
784105f3fe9SWaiman Long}
785105f3fe9SWaiman Long
786105f3fe9SWaiman Long#
78743a17fcfSWaiman Long# Check to see if there are unexpected isolated CPUs left beyond the boot
78843a17fcfSWaiman Long# time isolated ones.
78972c6303aSWaiman Long#
79072c6303aSWaiman Longnull_isolcpus_check()
79172c6303aSWaiman Long{
79272c6303aSWaiman Long	[[ $VERBOSE -gt 0 ]] || return 0
793877c737dSWaiman Long	# Retry a few times before printing error
794877c737dSWaiman Long	RETRY=0
79543ee4014SWaiman Long	while [[ $RETRY -lt 8 ]]
796877c737dSWaiman Long	do
79743ee4014SWaiman Long		pause 0.02
79872c6303aSWaiman Long		check_isolcpus "."
799877c737dSWaiman Long		[[ $? -eq 0 ]] && return 0
800877c737dSWaiman Long		((RETRY++))
801877c737dSWaiman Long	done
80272c6303aSWaiman Long	echo "Unexpected isolated CPUs: $ISOLCPUS"
80372c6303aSWaiman Long	dump_states
80472c6303aSWaiman Long	exit 1
80572c6303aSWaiman Long}
80672c6303aSWaiman Long
80772c6303aSWaiman Long#
808*b2b2b4d0SWaiman Long# Check state transition test result
809*b2b2b4d0SWaiman Long#  $1 - Test number
810*b2b2b4d0SWaiman Long#  $2 - Expected effective CPU values
811*b2b2b4d0SWaiman Long#  $3 - Expected partition states
812*b2b2b4d0SWaiman Long#  $4 - Expected isolated CPUs
813*b2b2b4d0SWaiman Long#
814*b2b2b4d0SWaiman Longcheck_test_results()
815*b2b2b4d0SWaiman Long{
816*b2b2b4d0SWaiman Long	_NR=$1
817*b2b2b4d0SWaiman Long	_ECPUS="$2"
818*b2b2b4d0SWaiman Long	_PSTATES="$3"
819*b2b2b4d0SWaiman Long	_ISOLCPUS="$4"
820*b2b2b4d0SWaiman Long
821*b2b2b4d0SWaiman Long	[[ -n "$_ECPUS" && "$_ECPUS" != . ]] && {
822*b2b2b4d0SWaiman Long		check_effective_cpus $_ECPUS
823*b2b2b4d0SWaiman Long		[[ $? -ne 0 ]] && test_fail $_NR "effective CPU" \
824*b2b2b4d0SWaiman Long			 "Cgroup $CGRP: expected $EXPECTED_CPUS, got $ACTUAL_CPUS"
825*b2b2b4d0SWaiman Long	}
826*b2b2b4d0SWaiman Long
827*b2b2b4d0SWaiman Long	[[ -n "$_PSTATES" && "$_PSTATES" != . ]] && {
828*b2b2b4d0SWaiman Long		check_cgroup_states $_PSTATES
829*b2b2b4d0SWaiman Long		[[ $? -ne 0 ]] && test_fail $_NR states \
830*b2b2b4d0SWaiman Long			"Cgroup $CGRP: expected $EXPECTED_STATE, got $ACTUAL_STATE"
831*b2b2b4d0SWaiman Long	}
832*b2b2b4d0SWaiman Long
833*b2b2b4d0SWaiman Long	# Compare the expected isolated CPUs with the actual ones,
834*b2b2b4d0SWaiman Long	# if available
835*b2b2b4d0SWaiman Long	[[ -n "$_ISOLCPUS" ]] && {
836*b2b2b4d0SWaiman Long		check_isolcpus $_ISOLCPUS
837*b2b2b4d0SWaiman Long		[[ $? -ne 0 ]] && {
838*b2b2b4d0SWaiman Long			[[ -n "$BOOT_ISOLCPUS" ]] && _ISOLCPUS=${_ISOLCPUS},${BOOT_ISOLCPUS}
839*b2b2b4d0SWaiman Long			test_fail $_NR "isolated CPU" \
840*b2b2b4d0SWaiman Long				"Expect $_ISOLCPUS, get $ISOLCPUS instead"
841*b2b2b4d0SWaiman Long		}
842*b2b2b4d0SWaiman Long	}
843*b2b2b4d0SWaiman Long	reset_cgroup_states
844*b2b2b4d0SWaiman Long	#
845*b2b2b4d0SWaiman Long	# Check to see if effective cpu list changes
846*b2b2b4d0SWaiman Long	#
847*b2b2b4d0SWaiman Long	_NEWLIST=$(cat $CGROUP2/cpuset.cpus.effective)
848*b2b2b4d0SWaiman Long	RETRY=0
849*b2b2b4d0SWaiman Long	while [[ $_NEWLIST != $CPULIST && $RETRY -lt 8 ]]
850*b2b2b4d0SWaiman Long	do
851*b2b2b4d0SWaiman Long		# Wait a bit longer & recheck a few times
852*b2b2b4d0SWaiman Long		pause 0.02
853*b2b2b4d0SWaiman Long		((RETRY++))
854*b2b2b4d0SWaiman Long		_NEWLIST=$(cat $CGROUP2/cpuset.cpus.effective)
855*b2b2b4d0SWaiman Long	done
856*b2b2b4d0SWaiman Long	[[ $_NEWLIST != $CPULIST ]] && {
857*b2b2b4d0SWaiman Long		echo "Effective cpus changed to $_NEWLIST after test $_NR!"
858*b2b2b4d0SWaiman Long		exit 1
859*b2b2b4d0SWaiman Long	}
860*b2b2b4d0SWaiman Long	null_isolcpus_check
861*b2b2b4d0SWaiman Long	[[ $VERBOSE -gt 0 ]] && echo "Test $I done."
862*b2b2b4d0SWaiman Long}
863*b2b2b4d0SWaiman Long
864*b2b2b4d0SWaiman Long#
865a8c52ebaSWaiman Long# Run cpuset state transition test
866a8c52ebaSWaiman Long#  $1 - test matrix name
867a8c52ebaSWaiman Long#
868a8c52ebaSWaiman Long# This test is somewhat fragile as delays (sleep x) are added in various
869a8c52ebaSWaiman Long# places to make sure state changes are fully propagated before the next
870a8c52ebaSWaiman Long# action. These delays may need to be adjusted if running in a slower machine.
871a8c52ebaSWaiman Long#
872a8c52ebaSWaiman Longrun_state_test()
873a8c52ebaSWaiman Long{
874a8c52ebaSWaiman Long	TEST=$1
875a8c52ebaSWaiman Long	CONTROLLER=cpuset
876*b2b2b4d0SWaiman Long	CGROUP_LIST=". A1 A1/A2 A1/A2/A3 B1"
877*b2b2b4d0SWaiman Long	RESET_LIST="A1/A2/A3 A1/A2 A1 B1"
878a8c52ebaSWaiman Long	I=0
879a8c52ebaSWaiman Long	eval CNT="\${#$TEST[@]}"
880a8c52ebaSWaiman Long
881a8c52ebaSWaiman Long	reset_cgroup_states
882a8c52ebaSWaiman Long	console_msg "Running state transition test ..."
883a8c52ebaSWaiman Long
884a8c52ebaSWaiman Long	while [[ $I -lt $CNT ]]
885a8c52ebaSWaiman Long	do
88643ee4014SWaiman Long		echo "Running test $I ..." > $CONSOLE
887105f3fe9SWaiman Long		[[ $VERBOSE -gt 1 ]] && {
888105f3fe9SWaiman Long			echo ""
889105f3fe9SWaiman Long			eval echo \${$TEST[$I]}
890105f3fe9SWaiman Long		}
891a8c52ebaSWaiman Long		eval set -- "\${$TEST[$I]}"
892105f3fe9SWaiman Long		OLD_A1=$1
893105f3fe9SWaiman Long		OLD_A2=$2
894105f3fe9SWaiman Long		OLD_A3=$3
895105f3fe9SWaiman Long		OLD_B1=$4
896105f3fe9SWaiman Long		NEW_A1=$5
897105f3fe9SWaiman Long		NEW_A2=$6
898105f3fe9SWaiman Long		NEW_A3=$7
899105f3fe9SWaiman Long		NEW_B1=$8
900105f3fe9SWaiman Long		RESULT=$9
901105f3fe9SWaiman Long		ECPUS=${10}
902105f3fe9SWaiman Long		STATES=${11}
903105f3fe9SWaiman Long		ICPUS=${12}
904a8c52ebaSWaiman Long
905105f3fe9SWaiman Long		set_ctrl_state_noerr B1       $OLD_B1
906a8c52ebaSWaiman Long		set_ctrl_state_noerr A1       $OLD_A1
907a8c52ebaSWaiman Long		set_ctrl_state_noerr A1/A2    $OLD_A2
908a8c52ebaSWaiman Long		set_ctrl_state_noerr A1/A2/A3 $OLD_A3
909a8c52ebaSWaiman Long		RETVAL=0
910a8c52ebaSWaiman Long		set_ctrl_state A1       $NEW_A1; ((RETVAL += $?))
911a8c52ebaSWaiman Long		set_ctrl_state A1/A2    $NEW_A2; ((RETVAL += $?))
912a8c52ebaSWaiman Long		set_ctrl_state A1/A2/A3 $NEW_A3; ((RETVAL += $?))
913a8c52ebaSWaiman Long		set_ctrl_state B1       $NEW_B1; ((RETVAL += $?))
914a8c52ebaSWaiman Long
915105f3fe9SWaiman Long		[[ $RETVAL -ne $RESULT ]] && test_fail $I result
916a8c52ebaSWaiman Long
917*b2b2b4d0SWaiman Long		check_test_results $I "$ECPUS" "$STATES" "$ICPUS"
918a8c52ebaSWaiman Long		((I++))
919a8c52ebaSWaiman Long	done
920a8c52ebaSWaiman Long	echo "All $I tests of $TEST PASSED."
921a8c52ebaSWaiman Long}
922a8c52ebaSWaiman Long
923a8c52ebaSWaiman Long#
92414060dfcSWaiman Long# Testing the new "isolated" partition root type
92514060dfcSWaiman Long#
92614060dfcSWaiman Longtest_isolated()
92714060dfcSWaiman Long{
92814060dfcSWaiman Long	cd $CGROUP2/test
92914060dfcSWaiman Long	echo 2-3 > cpuset.cpus
93014060dfcSWaiman Long	TYPE=$(cat cpuset.cpus.partition)
93114060dfcSWaiman Long	[[ $TYPE = member ]] || echo member > cpuset.cpus.partition
93214060dfcSWaiman Long
93314060dfcSWaiman Long	console_msg "Change from member to root"
93414060dfcSWaiman Long	test_partition root
93514060dfcSWaiman Long
93614060dfcSWaiman Long	console_msg "Change from root to isolated"
93714060dfcSWaiman Long	test_partition isolated
93814060dfcSWaiman Long
93914060dfcSWaiman Long	console_msg "Change from isolated to member"
94014060dfcSWaiman Long	test_partition member
94114060dfcSWaiman Long
94214060dfcSWaiman Long	console_msg "Change from member to isolated"
94314060dfcSWaiman Long	test_partition isolated
94414060dfcSWaiman Long
94514060dfcSWaiman Long	console_msg "Change from isolated to root"
94614060dfcSWaiman Long	test_partition root
94714060dfcSWaiman Long
94814060dfcSWaiman Long	console_msg "Change from root to member"
94914060dfcSWaiman Long	test_partition member
95014060dfcSWaiman Long
95114060dfcSWaiman Long	#
95214060dfcSWaiman Long	# Testing partition root with no cpu
95314060dfcSWaiman Long	#
95414060dfcSWaiman Long	console_msg "Distribute all cpus to child partition"
95514060dfcSWaiman Long	echo +cpuset > cgroup.subtree_control
95614060dfcSWaiman Long	test_partition root
95714060dfcSWaiman Long
95814060dfcSWaiman Long	mkdir A1
95914060dfcSWaiman Long	cd A1
96014060dfcSWaiman Long	echo 2-3 > cpuset.cpus
96114060dfcSWaiman Long	test_partition root
96214060dfcSWaiman Long	test_effective_cpus 2-3
96314060dfcSWaiman Long	cd ..
96414060dfcSWaiman Long	test_effective_cpus ""
96514060dfcSWaiman Long
96614060dfcSWaiman Long	console_msg "Moving task to partition test"
96714060dfcSWaiman Long	test_add_proc "No space left"
96814060dfcSWaiman Long	cd A1
96914060dfcSWaiman Long	test_add_proc ""
97014060dfcSWaiman Long	cd ..
97114060dfcSWaiman Long
97214060dfcSWaiman Long	console_msg "Shrink and expand child partition"
97314060dfcSWaiman Long	cd A1
97414060dfcSWaiman Long	echo 2 > cpuset.cpus
97514060dfcSWaiman Long	cd ..
97614060dfcSWaiman Long	test_effective_cpus 3
97714060dfcSWaiman Long	cd A1
97814060dfcSWaiman Long	echo 2-3 > cpuset.cpus
97914060dfcSWaiman Long	cd ..
98014060dfcSWaiman Long	test_effective_cpus ""
98114060dfcSWaiman Long
98214060dfcSWaiman Long	# Cleaning up
98314060dfcSWaiman Long	console_msg "Cleaning up"
98414060dfcSWaiman Long	echo $$ > $CGROUP2/cgroup.procs
98514060dfcSWaiman Long	[[ -d A1 ]] && rmdir A1
98672c6303aSWaiman Long	null_isolcpus_check
987*b2b2b4d0SWaiman Long	pause 0.05
98814060dfcSWaiman Long}
98914060dfcSWaiman Long
99014060dfcSWaiman Long#
991a8c52ebaSWaiman Long# Wait for inotify event for the given file and read it
992a8c52ebaSWaiman Long# $1: cgroup file to wait for
993a8c52ebaSWaiman Long# $2: file to store the read result
994a8c52ebaSWaiman Long#
995a8c52ebaSWaiman Longwait_inotify()
996a8c52ebaSWaiman Long{
997a8c52ebaSWaiman Long	CGROUP_FILE=$1
998a8c52ebaSWaiman Long	OUTPUT_FILE=$2
999a8c52ebaSWaiman Long
1000a8c52ebaSWaiman Long	$WAIT_INOTIFY $CGROUP_FILE
1001a8c52ebaSWaiman Long	cat $CGROUP_FILE > $OUTPUT_FILE
1002a8c52ebaSWaiman Long}
1003a8c52ebaSWaiman Long
1004a8c52ebaSWaiman Long#
1005a8c52ebaSWaiman Long# Test if inotify events are properly generated when going into and out of
1006a8c52ebaSWaiman Long# invalid partition state.
1007a8c52ebaSWaiman Long#
1008a8c52ebaSWaiman Longtest_inotify()
1009a8c52ebaSWaiman Long{
1010a8c52ebaSWaiman Long	ERR=0
1011a8c52ebaSWaiman Long	PRS=/tmp/.prs_$$
1012105f3fe9SWaiman Long	cd $CGROUP2/test
1013a8c52ebaSWaiman Long	[[ -f $WAIT_INOTIFY ]] || {
1014a8c52ebaSWaiman Long		echo "wait_inotify not found, inotify test SKIPPED."
1015a8c52ebaSWaiman Long		return
1016a8c52ebaSWaiman Long	}
1017a8c52ebaSWaiman Long
1018a8c52ebaSWaiman Long	pause 0.01
1019a8c52ebaSWaiman Long	echo 1 > cpuset.cpus
1020a8c52ebaSWaiman Long	echo 0 > cgroup.procs
1021a8c52ebaSWaiman Long	echo root > cpuset.cpus.partition
1022a8c52ebaSWaiman Long	pause 0.01
1023a8c52ebaSWaiman Long	rm -f $PRS
1024a8c52ebaSWaiman Long	wait_inotify $PWD/cpuset.cpus.partition $PRS &
1025a8c52ebaSWaiman Long	pause 0.01
1026105f3fe9SWaiman Long	set_ctrl_state . "O1=0"
1027a8c52ebaSWaiman Long	pause 0.01
1028a8c52ebaSWaiman Long	check_cgroup_states ".:P-1"
1029a8c52ebaSWaiman Long	if [[ $? -ne 0 ]]
1030a8c52ebaSWaiman Long	then
1031a8c52ebaSWaiman Long		echo "FAILED: Inotify test - partition not invalid"
1032a8c52ebaSWaiman Long		ERR=1
1033a8c52ebaSWaiman Long	elif [[ ! -f $PRS ]]
1034a8c52ebaSWaiman Long	then
1035a8c52ebaSWaiman Long		echo "FAILED: Inotify test - event not generated"
1036a8c52ebaSWaiman Long		ERR=1
1037a8c52ebaSWaiman Long		kill %1
1038a8c52ebaSWaiman Long	elif [[ $(cat $PRS) != "root invalid"* ]]
1039a8c52ebaSWaiman Long	then
1040a8c52ebaSWaiman Long		echo "FAILED: Inotify test - incorrect state"
1041a8c52ebaSWaiman Long		cat $PRS
1042a8c52ebaSWaiman Long		ERR=1
1043a8c52ebaSWaiman Long	fi
1044a8c52ebaSWaiman Long	online_cpus
1045a8c52ebaSWaiman Long	echo member > cpuset.cpus.partition
1046a8c52ebaSWaiman Long	echo 0 > ../cgroup.procs
1047a8c52ebaSWaiman Long	if [[ $ERR -ne 0 ]]
1048a8c52ebaSWaiman Long	then
1049a8c52ebaSWaiman Long		exit 1
1050a8c52ebaSWaiman Long	else
1051a8c52ebaSWaiman Long		echo "Inotify test PASSED"
1052a8c52ebaSWaiman Long	fi
1053*b2b2b4d0SWaiman Long	echo member > cpuset.cpus.partition
1054*b2b2b4d0SWaiman Long	echo "" > cpuset.cpus
1055a8c52ebaSWaiman Long}
1056a8c52ebaSWaiman Long
10571e85591dSKamalesh Babulaltrap cleanup 0 2 3 6
1058a8c52ebaSWaiman Longrun_state_test TEST_MATRIX
1059a8c52ebaSWaiman Longtest_isolated
1060a8c52ebaSWaiman Longtest_inotify
1061a8c52ebaSWaiman Longecho "All tests PASSED."
1062