xref: /linux/tools/testing/selftests/cgroup/test_cpuset_prs.sh (revision 36ec807b627b4c0a0a382f0ae48eac7187d14b2b)
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
871e85591dSKamalesh Babulalcleanup()
881e85591dSKamalesh Babulal{
891e85591dSKamalesh Babulal	online_cpus
90105f3fe9SWaiman Long	cd $CGROUP2
911e85591dSKamalesh Babulal	rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1
921e85591dSKamalesh Babulal	rmdir test > /dev/null 2>&1
931bf33285SWaiman Long	[[ -n "$SCHED_DEBUG" ]] &&
941e85591dSKamalesh Babulal		echo "$SCHED_DEBUG" > /sys/kernel/debug/sched/verbose
951e85591dSKamalesh Babulal}
961e85591dSKamalesh Babulal
97a8c52ebaSWaiman Long# Pause in ms
98a8c52ebaSWaiman Longpause()
99a8c52ebaSWaiman Long{
100a8c52ebaSWaiman Long	DELAY=$1
101a8c52ebaSWaiman Long	LOOP=0
102a8c52ebaSWaiman Long	while [[ $LOOP -lt $DELAY_FACTOR ]]
103a8c52ebaSWaiman Long	do
104a8c52ebaSWaiman Long		sleep $DELAY
105a8c52ebaSWaiman Long		((LOOP++))
106a8c52ebaSWaiman Long	done
107a8c52ebaSWaiman Long	return 0
108a8c52ebaSWaiman Long}
109a8c52ebaSWaiman Long
110a8c52ebaSWaiman Longconsole_msg()
111a8c52ebaSWaiman Long{
112a8c52ebaSWaiman Long	MSG=$1
113a8c52ebaSWaiman Long	echo "$MSG"
11443ee4014SWaiman Long	echo "" > $CONSOLE
11543ee4014SWaiman Long	echo "$MSG" > $CONSOLE
116a8c52ebaSWaiman Long	pause 0.01
117a8c52ebaSWaiman Long}
118a8c52ebaSWaiman Long
119a8c52ebaSWaiman Longtest_partition()
120a8c52ebaSWaiman Long{
121a8c52ebaSWaiman Long	EXPECTED_VAL=$1
122a8c52ebaSWaiman Long	echo $EXPECTED_VAL > cpuset.cpus.partition
123a8c52ebaSWaiman Long	[[ $? -eq 0 ]] || exit 1
124a8c52ebaSWaiman Long	ACTUAL_VAL=$(cat cpuset.cpus.partition)
125a8c52ebaSWaiman Long	[[ $ACTUAL_VAL != $EXPECTED_VAL ]] && {
126105f3fe9SWaiman Long		echo "cpuset.cpus.partition: expect $EXPECTED_VAL, found $ACTUAL_VAL"
127a8c52ebaSWaiman Long		echo "Test FAILED"
128a8c52ebaSWaiman Long		exit 1
129a8c52ebaSWaiman Long	}
130a8c52ebaSWaiman Long}
131a8c52ebaSWaiman Long
132a8c52ebaSWaiman Longtest_effective_cpus()
133a8c52ebaSWaiman Long{
134a8c52ebaSWaiman Long	EXPECTED_VAL=$1
135a8c52ebaSWaiman Long	ACTUAL_VAL=$(cat cpuset.cpus.effective)
136a8c52ebaSWaiman Long	[[ "$ACTUAL_VAL" != "$EXPECTED_VAL" ]] && {
137105f3fe9SWaiman Long		echo "cpuset.cpus.effective: expect '$EXPECTED_VAL', found '$ACTUAL_VAL'"
138a8c52ebaSWaiman Long		echo "Test FAILED"
139a8c52ebaSWaiman Long		exit 1
140a8c52ebaSWaiman Long	}
141a8c52ebaSWaiman Long}
142a8c52ebaSWaiman Long
143a8c52ebaSWaiman Long# Adding current process to cgroup.procs as a test
144a8c52ebaSWaiman Longtest_add_proc()
145a8c52ebaSWaiman Long{
146a8c52ebaSWaiman Long	OUTSTR="$1"
147a8c52ebaSWaiman Long	ERRMSG=$((echo $$ > cgroup.procs) |& cat)
148a8c52ebaSWaiman Long	echo $ERRMSG | grep -q "$OUTSTR"
149a8c52ebaSWaiman Long	[[ $? -ne 0 ]] && {
150a8c52ebaSWaiman Long		echo "cgroup.procs: expect '$OUTSTR', got '$ERRMSG'"
151a8c52ebaSWaiman Long		echo "Test FAILED"
152a8c52ebaSWaiman Long		exit 1
153a8c52ebaSWaiman Long	}
154a8c52ebaSWaiman Long	echo $$ > $CGROUP2/cgroup.procs	# Move out the task
155a8c52ebaSWaiman Long}
156a8c52ebaSWaiman Long
157a8c52ebaSWaiman Long#
158a8c52ebaSWaiman Long# Cpuset controller state transition test matrix.
159a8c52ebaSWaiman Long#
160a8c52ebaSWaiman Long# Cgroup test hierarchy
161a8c52ebaSWaiman Long#
162105f3fe9SWaiman Long# root -- A1 -- A2 -- A3
163105f3fe9SWaiman Long#      +- B1
164a8c52ebaSWaiman Long#
165105f3fe9SWaiman Long#  P<v> = set cpus.partition (0:member, 1:root, 2:isolated)
16646c521baSWaiman Long#  C<l> = add cpu-list to cpuset.cpus
16746c521baSWaiman Long#  X<l> = add cpu-list to cpuset.cpus.exclusive
168a8c52ebaSWaiman Long#  S<p> = use prefix in subtree_control
169a8c52ebaSWaiman Long#  T    = put a task into cgroup
170105f3fe9SWaiman Long#  O<c>=<v> = Write <v> to CPU online file of <c>
171a8c52ebaSWaiman Long#
172*1c0be3f7SWaiman Long# ECPUs    - effective CPUs of cpusets
173*1c0be3f7SWaiman Long# Pstate   - partition root state
174*1c0be3f7SWaiman Long# ISOLCPUS - isolated CPUs (<icpus>[,<icpus2>])
175*1c0be3f7SWaiman Long#
176*1c0be3f7SWaiman Long# Note that if there are 2 fields in ISOLCPUS, the first one is for
177*1c0be3f7SWaiman Long# sched-debug matching which includes offline CPUs and single-CPU partitions
178*1c0be3f7SWaiman Long# while the second one is for matching cpuset.cpus.isolated.
179*1c0be3f7SWaiman Long#
180a8c52ebaSWaiman LongSETUP_A123_PARTITIONS="C1-3:P1:S+ C2-3:P1:S+ C3:P1"
181a8c52ebaSWaiman LongTEST_MATRIX=(
182105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
183105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
184105f3fe9SWaiman Long	"   C0-1     .      .    C2-3    S+    C4-5     .      .     0 A2:0-1"
185105f3fe9SWaiman Long	"   C0-1     .      .    C2-3    P1      .      .      .     0 "
186105f3fe9SWaiman Long	"   C0-1     .      .    C2-3   P1:S+ C0-1:P1   .      .     0 "
187105f3fe9SWaiman Long	"   C0-1     .      .    C2-3   P1:S+  C1:P1    .      .     0 "
188105f3fe9SWaiman Long	"  C0-1:S+   .      .    C2-3     .      .      .     P1     0 "
189105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+     C1      .      .     0 "
190105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+    C1:P1    .      .     0 "
191105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+    C1:P1    .     P1     0 "
192105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3   C4-5     .      .      .     0 A1:4-5"
193105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3  S+:C4-5   .      .      .     0 A1:4-5"
194105f3fe9SWaiman Long	"   C0-1     .      .   C2-3:P1   .      .      .     C2     0 "
195105f3fe9SWaiman Long	"   C0-1     .      .   C2-3:P1   .      .      .    C4-5    0 B1:4-5"
196105f3fe9SWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .      .      .      .      .     0 A1:0-1,A2:2-3"
197105f3fe9SWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     C1-3    .      .      .     0 A1:1,A2:2-3"
198105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .     C3      .      .      .     0 A1:,A2:3 A1:P1,A2:P1"
199105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .     C3      P0     .      .     0 A1:3,A2:3 A1:P1,A2:P0"
200105f3fe9SWaiman Long	"C2-3:P1:S+  C2:P1  .      .     C2-4    .      .      .     0 A1:3-4,A2:2"
201105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .     C3      .      .     C0-2   0 A1:,B1:0-2 A1:P1,A2:P1"
202105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .     C2-3    .      .      .     0 A1:,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
203a8c52ebaSWaiman Long
204a8c52ebaSWaiman Long	# CPU offlining cases:
205105f3fe9SWaiman Long	"   C0-1     .      .    C2-3    S+    C4-5     .     O2=0   0 A1:0-1,B1:3"
206105f3fe9SWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O2=0    .      .      .     0 A1:0-1,A2:3"
207105f3fe9SWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O2=0   O2=1    .      .     0 A1:0-1,A2:2-3"
208105f3fe9SWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O1=0    .      .      .     0 A1:0,A2:2-3"
209105f3fe9SWaiman Long	"C0-3:P1:S+ C2-3:P1 .      .     O1=0   O1=1    .      .     0 A1:0-1,A2:2-3"
210105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O3=0   O3=1    .      .     0 A1:2,A2:3 A1:P1,A2:P1"
211105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P2  .      .     O3=0   O3=1    .      .     0 A1:2,A2:3 A1:P1,A2:P2"
212105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O2=0   O2=1    .      .     0 A1:2,A2:3 A1:P1,A2:P1"
213105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P2  .      .     O2=0   O2=1    .      .     0 A1:2,A2:3 A1:P1,A2:P2"
214105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O2=0    .      .      .     0 A1:,A2:3 A1:P1,A2:P1"
215105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .     O3=0    .      .      .     0 A1:2,A2: A1:P1,A2:P1"
216105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .    T:O2=0   .      .      .     0 A1:3,A2:3 A1:P1,A2:P-1"
217105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .      .    T:O3=0   .      .     0 A1:2,A2:2 A1:P1,A2:P-1"
218105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .     O1=0    .      .      .     0 A1:,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
219105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .     O2=0    .      .      .     0 A1:1,A2:,A3:3 A1:P1,A2:P1,A3:P1"
220105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .     O3=0    .      .      .     0 A1:1,A2:2,A3: A1:P1,A2:P1,A3:P1"
221105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0   .      .      .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1"
222105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .      .    T:O2=0   .      .     0 A1:1,A2:3,A3:3 A1:P1,A2:P1,A3:P-1"
223105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .      .      .    T:O3=0   .     0 A1:1,A2:2,A3:2 A1:P1,A2:P1,A3:P-1"
224105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0  O1=1    .      .     0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
225105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .      .    T:O2=0  O2=1    .     0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
226105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .      .      .    T:O3=0  O3=1   0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
227105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .    T:O1=0  O2=0   O1=1    .     0 A1:1,A2:,A3:3 A1:P1,A2:P1,A3:P1"
228105f3fe9SWaiman 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"
229a8c52ebaSWaiman Long
230105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
231105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
232105f3fe9SWaiman Long	#
233105f3fe9SWaiman Long	# Remote partition and cpuset.cpus.exclusive tests
234105f3fe9SWaiman Long	#
235105f3fe9SWaiman Long	" C0-3:S+ C1-3:S+ C2-3     .    X2-3     .      .      .     0 A1:0-3,A2:1-3,A3:2-3,XA1:2-3"
236105f3fe9SWaiman 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"
237105f3fe9SWaiman 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"
238105f3fe9SWaiman 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"
239*1c0be3f7SWaiman 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"
240105f3fe9SWaiman 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"
241105f3fe9SWaiman Long	" C0-3:S+ C1-3:S+ C2-3   C4-5     .      .      .      P2    0 B1:4-5 B1:P2 4-5"
242105f3fe9SWaiman 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"
243105f3fe9SWaiman 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"
244105f3fe9SWaiman 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"
245105f3fe9SWaiman 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"
246*1c0be3f7SWaiman Long	" C4:X0-3:S+ X1-3:S+ X2-3  .      .      P2     .      .     0 A1:4,A2:1-3,A3:1-3 A2:P2 1-3"
247*1c0be3f7SWaiman Long	" C4:X0-3:S+ X1-3:S+ X2-3  .      .      .      P2     .     0 A1:4,A2:4,A3:2-3 A3:P2 2-3"
248105f3fe9SWaiman Long
249105f3fe9SWaiman Long	# Nested remote/local partition tests
250105f3fe9SWaiman 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 \
251105f3fe9SWaiman Long								       A1:P0,A2:P1,A3:P2,B1:P1 2-3"
252105f3fe9SWaiman 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 \
25372c6303aSWaiman Long								       A1:P0,A2:P1,A3:P2,B1:P1 2-4,2-3"
254*1c0be3f7SWaiman 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 \
255*1c0be3f7SWaiman Long								       A1:P0,A2:P1,A3:P0,B1:P1"
256105f3fe9SWaiman 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 \
25772c6303aSWaiman Long								       A1:P0,A2:P1,A3:P2,B1:P1 2-4,3"
258105f3fe9SWaiman 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 \
25972c6303aSWaiman Long								       A1:P0,A2:P2,A3:P1 2-4,2-3"
260*1c0be3f7SWaiman 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 \
261*1c0be3f7SWaiman Long								       A1:P0,A2:P2,A3:P1 2"
262105f3fe9SWaiman Long	" C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \
263105f3fe9SWaiman Long				   .      .      X5      .      .    0 A1:0-4,A2:1-4,A3:2-4 \
26414060dfcSWaiman Long								       A1:P0,A2:P-2,A3:P-1"
265105f3fe9SWaiman Long	" C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \
266105f3fe9SWaiman Long				   .      .      .      X1      .    0 A1:0-1,A2:2-4,A3:2-4 \
267105f3fe9SWaiman Long								       A1:P0,A2:P2,A3:P-1 2-4"
268105f3fe9SWaiman Long
269105f3fe9SWaiman Long	# Remote partition offline tests
270105f3fe9SWaiman 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"
271105f3fe9SWaiman 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"
272105f3fe9SWaiman 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"
27372c6303aSWaiman 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,"
274105f3fe9SWaiman Long
275105f3fe9SWaiman Long	# An invalidated remote partition cannot self-recover from hotplug
276105f3fe9SWaiman 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"
277105f3fe9SWaiman Long
278105f3fe9SWaiman Long	# cpus.exclusive.effective clearing test
279105f3fe9SWaiman Long	" C0-3:S+ C1-3:S+  C2      .   X2-3:X    .      .      .     0 A1:0-3,A2:1-3,A3:2,XA1:"
280105f3fe9SWaiman Long
28146c521baSWaiman Long	# Invalid to valid remote partition transition test
282105f3fe9SWaiman Long	" C0-3:S+   C1-3    .      .      .    X3:P2    .      .     0 A1:0-3,A2:1-3,XA2: A2:P-2"
283105f3fe9SWaiman Long	" C0-3:S+ C1-3:X3:P2
28446c521baSWaiman Long			    .      .    X2-3    P2      .      .     0 A1:0-2,A2:3,XA2:3 A2:P2 3"
285105f3fe9SWaiman Long
286105f3fe9SWaiman Long	# Invalid to valid local partition direct transition tests
287*1c0be3f7SWaiman 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"
288*1c0be3f7SWaiman 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"
28946c521baSWaiman Long	"  C0-3:P2   .      .    C4-6   C0-4     .      .      .     0 A1:0-4,B1:4-6 A1:P-2,B1:P0"
29046c521baSWaiman Long	"  C0-3:P2   .      .    C4-6 C0-4:C0-3  .      .      .     0 A1:0-3,B1:4-6 A1:P2,B1:P0 0-3"
29146c521baSWaiman Long	"  C0-3:P2   .      .  C3-5:C4-5  .      .      .      .     0 A1:0-3,B1:4-5 A1:P2,B1:P0 0-3"
292105f3fe9SWaiman Long
293105f3fe9SWaiman Long	# Local partition invalidation tests
294105f3fe9SWaiman Long	" C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \
295105f3fe9SWaiman Long				   .      .      .      .      .     0 A1:1,A2:2,A3:3 A1:P2,A2:P2,A3:P2 1-3"
296105f3fe9SWaiman Long	" C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \
297105f3fe9SWaiman Long				   .      .     X4      .      .     0 A1:1-3,A2:1-3,A3:2-3,XA2:,XA3: A1:P2,A2:P-2,A3:P-2 1-3"
298105f3fe9SWaiman Long	" C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \
299*1c0be3f7SWaiman 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"
30046c521baSWaiman Long	# Local partition CPU change tests
30146c521baSWaiman Long	" C0-5:S+:P2 C4-5:S+:P1 .  .      .    C3-5     .      .     0 A1:0-2,A2:3-5 A1:P2,A2:P1 0-2"
30246c521baSWaiman Long	" C0-5:S+:P2 C4-5:S+:P1 .  .    C1-5     .      .      .     0 A1:1-3,A2:4-5 A1:P2,A2:P1 1-3"
303105f3fe9SWaiman Long
304105f3fe9SWaiman Long	# cpus_allowed/exclusive_cpus update tests
305105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \
306*1c0be3f7SWaiman Long				   .    X:C4     .      P2     .     0 A1:4,A2:4,XA2:,XA3:,A3:4 \
30714060dfcSWaiman Long								       A1:P0,A3:P-2"
308105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \
309105f3fe9SWaiman Long				   .     X1      .      P2     .     0 A1:0-3,A2:1-3,XA1:1,XA2:,XA3:,A3:2-3 \
31014060dfcSWaiman Long								       A1:P0,A3:P-2"
311105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \
312105f3fe9SWaiman Long				   .      .     X3      P2     .     0 A1:0-2,A2:1-2,XA2:3,XA3:3,A3:3 \
313105f3fe9SWaiman Long								       A1:P0,A3:P2 3"
314105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \
315105f3fe9SWaiman Long				   .      .     X3      .      .     0 A1:0-3,A2:1-3,XA2:3,XA3:3,A3:2-3 \
31614060dfcSWaiman Long								       A1:P0,A3:P-2"
317105f3fe9SWaiman Long	" C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \
318*1c0be3f7SWaiman Long				   .     X4      .      .      .     0 A1:0-3,A2:1-3,A3:2-3,XA1:4,XA2:,XA3 \
31914060dfcSWaiman Long								       A1:P0,A3:P-2"
320105f3fe9SWaiman Long
321105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
322105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
323a8c52ebaSWaiman Long	#
324a8c52ebaSWaiman Long	# Incorrect change to cpuset.cpus invalidates partition root
325a8c52ebaSWaiman Long	#
326a8c52ebaSWaiman Long	# Adding CPUs to partition root that are not in parent's
327a8c52ebaSWaiman Long	# cpuset.cpus is allowed, but those extra CPUs are ignored.
328105f3fe9SWaiman Long	"C2-3:P1:S+ C3:P1   .      .      .     C2-4    .      .     0 A1:,A2:2-3 A1:P1,A2:P1"
329a8c52ebaSWaiman Long
330a8c52ebaSWaiman Long	# Taking away all CPUs from parent or itself if there are tasks
331a8c52ebaSWaiman Long	# will make the partition invalid.
332105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .      T     C2-3    .      .     0 A1:2-3,A2:2-3 A1:P1,A2:P-1"
333105f3fe9SWaiman Long	" C3:P1:S+    C3    .      .      T      P1     .      .     0 A1:3,A2:3 A1:P1,A2:P-1"
334105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .    T:C2-3   .      .      .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1"
335105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    . T:C2-3:C1-3 .      .      .     0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
336a8c52ebaSWaiman Long
337a8c52ebaSWaiman Long	# Changing a partition root to member makes child partitions invalid
338105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .      P0     .      .      .     0 A1:2-3,A2:3 A1:P0,A2:P-1"
339105f3fe9SWaiman Long	"$SETUP_A123_PARTITIONS    .     C2-3    P0     .      .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P0,A3:P-1"
340a8c52ebaSWaiman Long
341a8c52ebaSWaiman Long	# cpuset.cpus can contains cpus not in parent's cpuset.cpus as long
342a8c52ebaSWaiman Long	# as they overlap.
343105f3fe9SWaiman Long	"C2-3:P1:S+  .      .      .      .   C3-4:P1   .      .     0 A1:2,A2:3 A1:P1,A2:P1"
344a8c52ebaSWaiman Long
345a8c52ebaSWaiman Long	# Deletion of CPUs distributed to child cgroup is allowed.
346105f3fe9SWaiman Long	"C0-1:P1:S+ C1      .    C2-3   C4-5     .      .      .     0 A1:4-5,A2:4-5"
347a8c52ebaSWaiman Long
348a8c52ebaSWaiman Long	# To become a valid partition root, cpuset.cpus must overlap parent's
349a8c52ebaSWaiman Long	# cpuset.cpus.
350105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3    S+   C4-5:P1   .      .     0 A1:0-1,A2:0-1 A1:P1,A2:P-1"
351a8c52ebaSWaiman Long
352a8c52ebaSWaiman Long	# Enabling partition with child cpusets is allowed
353105f3fe9SWaiman Long	"  C0-1:S+  C1      .    C2-3    P1      .      .      .     0 A1:0-1,A2:1 A1:P1"
354a8c52ebaSWaiman Long
355a8c52ebaSWaiman Long	# A partition root with non-partition root parent is invalid, but it
356a8c52ebaSWaiman Long	# can be made valid if its parent becomes a partition root too.
357105f3fe9SWaiman Long	"  C0-1:S+  C1      .    C2-3     .      P2     .      .     0 A1:0-1,A2:1 A1:P0,A2:P-2"
358105f3fe9SWaiman Long	"  C0-1:S+ C1:P2    .    C2-3     P1     .      .      .     0 A1:0,A2:1 A1:P1,A2:P2"
359a8c52ebaSWaiman Long
360a8c52ebaSWaiman Long	# A non-exclusive cpuset.cpus change will invalidate partition and its siblings
361105f3fe9SWaiman Long	"  C0-1:P1   .      .    C2-3   C0-2     .      .      .     0 A1:0-2,B1:2-3 A1:P-1,B1:P0"
362105f3fe9SWaiman Long	"  C0-1:P1   .      .  P1:C2-3  C0-2     .      .      .     0 A1:0-2,B1:2-3 A1:P-1,B1:P-1"
363105f3fe9SWaiman Long	"   C0-1     .      .  P1:C2-3  C0-2     .      .      .     0 A1:0-2,B1:2-3 A1:P0,B1:P-1"
364a8c52ebaSWaiman Long
365*1c0be3f7SWaiman Long	# cpuset.cpus can overlap with sibling cpuset.cpus.exclusive but not subsumed by it
366*1c0be3f7SWaiman Long	"   C0-3     .      .    C4-5     X5     .      .      .     0 A1:0-3,B1:4-5"
367*1c0be3f7SWaiman Long
368105f3fe9SWaiman Long	#  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
369105f3fe9SWaiman Long	#  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
370a8c52ebaSWaiman Long	# Failure cases:
371a8c52ebaSWaiman Long
372a8c52ebaSWaiman Long	# A task cannot be added to a partition with no cpu
373105f3fe9SWaiman Long	"C2-3:P1:S+  C3:P1  .      .    O2=0:T   .      .      .     1 A1:,A2:3 A1:P1,A2:P1"
374105f3fe9SWaiman Long
375105f3fe9SWaiman Long	# Changes to cpuset.cpus.exclusive that violate exclusivity rule is rejected
376105f3fe9SWaiman Long	"   C0-3     .      .    C4-5   X0-3     .      .     X3-5   1 A1:0-3,B1:4-5"
377*1c0be3f7SWaiman Long
378*1c0be3f7SWaiman Long	# cpuset.cpus cannot be a subset of sibling cpuset.cpus.exclusive
379*1c0be3f7SWaiman Long	"   C0-3     .      .    C4-5   X3-5     .      .      .     1 A1:0-3,B1:4-5"
380a8c52ebaSWaiman Long)
381a8c52ebaSWaiman Long
382a8c52ebaSWaiman Long#
383a8c52ebaSWaiman Long# Write to the cpu online file
384105f3fe9SWaiman Long#  $1 - <c>=<v> where <c> = cpu number, <v> value to be written
385a8c52ebaSWaiman Long#
386a8c52ebaSWaiman Longwrite_cpu_online()
387a8c52ebaSWaiman Long{
388105f3fe9SWaiman Long	CPU=${1%=*}
389105f3fe9SWaiman Long	VAL=${1#*=}
390a8c52ebaSWaiman Long	CPUFILE=//sys/devices/system/cpu/cpu${CPU}/online
391a8c52ebaSWaiman Long	if [[ $VAL -eq 0 ]]
392a8c52ebaSWaiman Long	then
393a8c52ebaSWaiman Long		OFFLINE_CPUS="$OFFLINE_CPUS $CPU"
394a8c52ebaSWaiman Long	else
395a8c52ebaSWaiman Long		[[ -n "$OFFLINE_CPUS" ]] && {
396a8c52ebaSWaiman Long			OFFLINE_CPUS=$(echo $CPU $CPU $OFFLINE_CPUS | fmt -1 |\
397a8c52ebaSWaiman Long					sort | uniq -u)
398a8c52ebaSWaiman Long		}
399a8c52ebaSWaiman Long	fi
400a8c52ebaSWaiman Long	echo $VAL > $CPUFILE
40172c6303aSWaiman Long	pause 0.05
402a8c52ebaSWaiman Long}
403a8c52ebaSWaiman Long
404a8c52ebaSWaiman Long#
405a8c52ebaSWaiman Long# Set controller state
406a8c52ebaSWaiman Long#  $1 - cgroup directory
407a8c52ebaSWaiman Long#  $2 - state
408a8c52ebaSWaiman Long#  $3 - showerr
409a8c52ebaSWaiman Long#
410a8c52ebaSWaiman Long# The presence of ":" in state means transition from one to the next.
411a8c52ebaSWaiman Long#
412a8c52ebaSWaiman Longset_ctrl_state()
413a8c52ebaSWaiman Long{
414a8c52ebaSWaiman Long	TMPMSG=/tmp/.msg_$$
415a8c52ebaSWaiman Long	CGRP=$1
416a8c52ebaSWaiman Long	STATE=$2
417105f3fe9SWaiman Long	SHOWERR=${3}
418a8c52ebaSWaiman Long	CTRL=${CTRL:=$CONTROLLER}
419a8c52ebaSWaiman Long	HASERR=0
420a8c52ebaSWaiman Long	REDIRECT="2> $TMPMSG"
421a8c52ebaSWaiman Long	[[ -z "$STATE" || "$STATE" = '.' ]] && return 0
422105f3fe9SWaiman Long	[[ $VERBOSE -gt 0 ]] && SHOWERR=1
423a8c52ebaSWaiman Long
424a8c52ebaSWaiman Long	rm -f $TMPMSG
425a8c52ebaSWaiman Long	for CMD in $(echo $STATE | sed -e "s/:/ /g")
426a8c52ebaSWaiman Long	do
427a8c52ebaSWaiman Long		TFILE=$CGRP/cgroup.procs
428a8c52ebaSWaiman Long		SFILE=$CGRP/cgroup.subtree_control
429a8c52ebaSWaiman Long		PFILE=$CGRP/cpuset.cpus.partition
430a8c52ebaSWaiman Long		CFILE=$CGRP/cpuset.cpus
431105f3fe9SWaiman Long		XFILE=$CGRP/cpuset.cpus.exclusive
432a8c52ebaSWaiman Long		S=$(expr substr $CMD 1 1)
433a8c52ebaSWaiman Long		if [[ $S = S ]]
434a8c52ebaSWaiman Long		then
435a8c52ebaSWaiman Long			PREFIX=${CMD#?}
436a8c52ebaSWaiman Long			COMM="echo ${PREFIX}${CTRL} > $SFILE"
437a8c52ebaSWaiman Long			eval $COMM $REDIRECT
438105f3fe9SWaiman Long		elif [[ $S = X ]]
439105f3fe9SWaiman Long		then
440105f3fe9SWaiman Long			CPUS=${CMD#?}
441105f3fe9SWaiman Long			COMM="echo $CPUS > $XFILE"
442105f3fe9SWaiman Long			eval $COMM $REDIRECT
443a8c52ebaSWaiman Long		elif [[ $S = C ]]
444a8c52ebaSWaiman Long		then
445a8c52ebaSWaiman Long			CPUS=${CMD#?}
446a8c52ebaSWaiman Long			COMM="echo $CPUS > $CFILE"
447a8c52ebaSWaiman Long			eval $COMM $REDIRECT
448a8c52ebaSWaiman Long		elif [[ $S = P ]]
449a8c52ebaSWaiman Long		then
450a8c52ebaSWaiman Long			VAL=${CMD#?}
451a8c52ebaSWaiman Long			case $VAL in
452a8c52ebaSWaiman Long			0)  VAL=member
453a8c52ebaSWaiman Long			    ;;
454a8c52ebaSWaiman Long			1)  VAL=root
455a8c52ebaSWaiman Long			    ;;
456a8c52ebaSWaiman Long			2)  VAL=isolated
457a8c52ebaSWaiman Long			    ;;
458a8c52ebaSWaiman Long			*)
459a8c52ebaSWaiman Long			    echo "Invalid partition state - $VAL"
460a8c52ebaSWaiman Long			    exit 1
461a8c52ebaSWaiman Long			    ;;
462a8c52ebaSWaiman Long			esac
463a8c52ebaSWaiman Long			COMM="echo $VAL > $PFILE"
464a8c52ebaSWaiman Long			eval $COMM $REDIRECT
465a8c52ebaSWaiman Long		elif [[ $S = O ]]
466a8c52ebaSWaiman Long		then
467a8c52ebaSWaiman Long			VAL=${CMD#?}
468a8c52ebaSWaiman Long			write_cpu_online $VAL
469a8c52ebaSWaiman Long		elif [[ $S = T ]]
470a8c52ebaSWaiman Long		then
471a8c52ebaSWaiman Long			COMM="echo 0 > $TFILE"
472a8c52ebaSWaiman Long			eval $COMM $REDIRECT
473a8c52ebaSWaiman Long		fi
474a8c52ebaSWaiman Long		RET=$?
475a8c52ebaSWaiman Long		[[ $RET -ne 0 ]] && {
476a8c52ebaSWaiman Long			[[ -n "$SHOWERR" ]] && {
477a8c52ebaSWaiman Long				echo "$COMM"
478a8c52ebaSWaiman Long				cat $TMPMSG
479a8c52ebaSWaiman Long			}
480a8c52ebaSWaiman Long			HASERR=1
481a8c52ebaSWaiman Long		}
482a8c52ebaSWaiman Long		pause 0.01
483a8c52ebaSWaiman Long		rm -f $TMPMSG
484a8c52ebaSWaiman Long	done
485a8c52ebaSWaiman Long	return $HASERR
486a8c52ebaSWaiman Long}
487a8c52ebaSWaiman Long
488a8c52ebaSWaiman Longset_ctrl_state_noerr()
489a8c52ebaSWaiman Long{
490a8c52ebaSWaiman Long	CGRP=$1
491a8c52ebaSWaiman Long	STATE=$2
492a8c52ebaSWaiman Long	[[ -d $CGRP ]] || mkdir $CGRP
493a8c52ebaSWaiman Long	set_ctrl_state $CGRP $STATE 1
494a8c52ebaSWaiman Long	[[ $? -ne 0 ]] && {
495a8c52ebaSWaiman Long		echo "ERROR: Failed to set $2 to cgroup $1!"
496a8c52ebaSWaiman Long		exit 1
497a8c52ebaSWaiman Long	}
498a8c52ebaSWaiman Long}
499a8c52ebaSWaiman Long
500a8c52ebaSWaiman Longonline_cpus()
501a8c52ebaSWaiman Long{
502a8c52ebaSWaiman Long	[[ -n "OFFLINE_CPUS" ]] && {
503a8c52ebaSWaiman Long		for C in $OFFLINE_CPUS
504a8c52ebaSWaiman Long		do
505105f3fe9SWaiman Long			write_cpu_online ${C}=1
506a8c52ebaSWaiman Long		done
507a8c52ebaSWaiman Long	}
508a8c52ebaSWaiman Long}
509a8c52ebaSWaiman Long
510a8c52ebaSWaiman Long#
511a8c52ebaSWaiman Long# Return 1 if the list of effective cpus isn't the same as the initial list.
512a8c52ebaSWaiman Long#
513a8c52ebaSWaiman Longreset_cgroup_states()
514a8c52ebaSWaiman Long{
515a8c52ebaSWaiman Long	echo 0 > $CGROUP2/cgroup.procs
516a8c52ebaSWaiman Long	online_cpus
517a8c52ebaSWaiman Long	rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1
518105f3fe9SWaiman Long	pause 0.02
519105f3fe9SWaiman Long	set_ctrl_state . R-
520a8c52ebaSWaiman Long	pause 0.01
521a8c52ebaSWaiman Long}
522a8c52ebaSWaiman Long
523a8c52ebaSWaiman Longdump_states()
524a8c52ebaSWaiman Long{
525105f3fe9SWaiman Long	for DIR in . A1 A1/A2 A1/A2/A3 B1
526a8c52ebaSWaiman Long	do
527105f3fe9SWaiman Long		CPUS=$DIR/cpuset.cpus
528a8c52ebaSWaiman Long		ECPUS=$DIR/cpuset.cpus.effective
529105f3fe9SWaiman Long		XCPUS=$DIR/cpuset.cpus.exclusive
530105f3fe9SWaiman Long		XECPUS=$DIR/cpuset.cpus.exclusive.effective
531a8c52ebaSWaiman Long		PRS=$DIR/cpuset.cpus.partition
532105f3fe9SWaiman Long		PCPUS=$DIR/.__DEBUG__.cpuset.cpus.subpartitions
533877c737dSWaiman Long		ISCPUS=$DIR/cpuset.cpus.isolated
534105f3fe9SWaiman Long		[[ -e $CPUS   ]] && echo "$CPUS: $(cat $CPUS)"
535105f3fe9SWaiman Long		[[ -e $XCPUS  ]] && echo "$XCPUS: $(cat $XCPUS)"
536a8c52ebaSWaiman Long		[[ -e $ECPUS  ]] && echo "$ECPUS: $(cat $ECPUS)"
537105f3fe9SWaiman Long		[[ -e $XECPUS ]] && echo "$XECPUS: $(cat $XECPUS)"
538a8c52ebaSWaiman Long		[[ -e $PRS    ]] && echo "$PRS: $(cat $PRS)"
539105f3fe9SWaiman Long		[[ -e $PCPUS  ]] && echo "$PCPUS: $(cat $PCPUS)"
54072c6303aSWaiman Long		[[ -e $ISCPUS ]] && echo "$ISCPUS: $(cat $ISCPUS)"
541a8c52ebaSWaiman Long	done
542a8c52ebaSWaiman Long}
543a8c52ebaSWaiman Long
544a8c52ebaSWaiman Long#
545a8c52ebaSWaiman Long# Check effective cpus
546a8c52ebaSWaiman Long# $1 - check string, format: <cgroup>:<cpu-list>[,<cgroup>:<cpu-list>]*
547a8c52ebaSWaiman Long#
548a8c52ebaSWaiman Longcheck_effective_cpus()
549a8c52ebaSWaiman Long{
550a8c52ebaSWaiman Long	CHK_STR=$1
551a8c52ebaSWaiman Long	for CHK in $(echo $CHK_STR | sed -e "s/,/ /g")
552a8c52ebaSWaiman Long	do
553a8c52ebaSWaiman Long		set -- $(echo $CHK | sed -e "s/:/ /g")
554a8c52ebaSWaiman Long		CGRP=$1
555a8c52ebaSWaiman Long		CPUS=$2
556105f3fe9SWaiman Long		if [[ $CGRP = X* ]]
557105f3fe9SWaiman Long		then
558105f3fe9SWaiman Long			CGRP=${CGRP#X}
559105f3fe9SWaiman Long			FILE=cpuset.cpus.exclusive.effective
560105f3fe9SWaiman Long		else
561105f3fe9SWaiman Long			FILE=cpuset.cpus.effective
562105f3fe9SWaiman Long		fi
563a8c52ebaSWaiman Long		[[ $CGRP = A2 ]] && CGRP=A1/A2
564a8c52ebaSWaiman Long		[[ $CGRP = A3 ]] && CGRP=A1/A2/A3
565105f3fe9SWaiman Long		[[ -e $CGRP/$FILE ]] || return 1
566105f3fe9SWaiman Long		[[ $CPUS = $(cat $CGRP/$FILE) ]] || return 1
567a8c52ebaSWaiman Long	done
568a8c52ebaSWaiman Long}
569a8c52ebaSWaiman Long
570a8c52ebaSWaiman Long#
571a8c52ebaSWaiman Long# Check cgroup states
572a8c52ebaSWaiman Long#  $1 - check string, format: <cgroup>:<state>[,<cgroup>:<state>]*
573a8c52ebaSWaiman Long#
574a8c52ebaSWaiman Longcheck_cgroup_states()
575a8c52ebaSWaiman Long{
576a8c52ebaSWaiman Long	CHK_STR=$1
577a8c52ebaSWaiman Long	for CHK in $(echo $CHK_STR | sed -e "s/,/ /g")
578a8c52ebaSWaiman Long	do
579a8c52ebaSWaiman Long		set -- $(echo $CHK | sed -e "s/:/ /g")
580a8c52ebaSWaiman Long		CGRP=$1
581*1c0be3f7SWaiman Long		CGRP_DIR=$CGRP
582a8c52ebaSWaiman Long		STATE=$2
583a8c52ebaSWaiman Long		FILE=
584a8c52ebaSWaiman Long		EVAL=$(expr substr $STATE 2 2)
585*1c0be3f7SWaiman Long		[[ $CGRP = A2 ]] && CGRP_DIR=A1/A2
586*1c0be3f7SWaiman Long		[[ $CGRP = A3 ]] && CGRP_DIR=A1/A2/A3
587a8c52ebaSWaiman Long
588a8c52ebaSWaiman Long		case $STATE in
589*1c0be3f7SWaiman Long			P*) FILE=$CGRP_DIR/cpuset.cpus.partition
590a8c52ebaSWaiman Long			    ;;
591a8c52ebaSWaiman Long			*)  echo "Unknown state: $STATE!"
592a8c52ebaSWaiman Long			    exit 1
593a8c52ebaSWaiman Long			    ;;
594a8c52ebaSWaiman Long		esac
595a8c52ebaSWaiman Long		VAL=$(cat $FILE)
596a8c52ebaSWaiman Long
597a8c52ebaSWaiman Long		case "$VAL" in
598a8c52ebaSWaiman Long			member) VAL=0
599a8c52ebaSWaiman Long				;;
600a8c52ebaSWaiman Long			root)	VAL=1
601a8c52ebaSWaiman Long				;;
602a8c52ebaSWaiman Long			isolated)
603a8c52ebaSWaiman Long				VAL=2
604a8c52ebaSWaiman Long				;;
605a8c52ebaSWaiman Long			"root invalid"*)
606a8c52ebaSWaiman Long				VAL=-1
607a8c52ebaSWaiman Long				;;
608a8c52ebaSWaiman Long			"isolated invalid"*)
609a8c52ebaSWaiman Long				VAL=-2
610a8c52ebaSWaiman Long				;;
611a8c52ebaSWaiman Long		esac
612a8c52ebaSWaiman Long		[[ $EVAL != $VAL ]] && return 1
613*1c0be3f7SWaiman Long
614*1c0be3f7SWaiman Long		#
615*1c0be3f7SWaiman Long		# For root partition, dump sched-domains info to console if
616*1c0be3f7SWaiman Long		# verbose mode set for manual comparison with sched debug info.
617*1c0be3f7SWaiman Long		#
618*1c0be3f7SWaiman Long		[[ $VAL -eq 1 && $VERBOSE -gt 0 ]] && {
619*1c0be3f7SWaiman Long			DOMS=$(cat $CGRP_DIR/cpuset.cpus.effective)
620*1c0be3f7SWaiman Long			[[ -n "$DOMS" ]] &&
621*1c0be3f7SWaiman Long				echo " [$CGRP] sched-domain: $DOMS" > $CONSOLE
622*1c0be3f7SWaiman Long		}
623a8c52ebaSWaiman Long	done
624a8c52ebaSWaiman Long	return 0
625a8c52ebaSWaiman Long}
626a8c52ebaSWaiman Long
627a8c52ebaSWaiman Long#
628105f3fe9SWaiman Long# Get isolated (including offline) CPUs by looking at
629877c737dSWaiman Long# /sys/kernel/debug/sched/domains and cpuset.cpus.isolated control file,
63072c6303aSWaiman Long# if available, and compare that with the expected value.
631105f3fe9SWaiman Long#
63272c6303aSWaiman Long# Note that isolated CPUs from the sched/domains context include offline
63372c6303aSWaiman Long# CPUs as well as CPUs in non-isolated 1-CPU partition. Those CPUs may
634877c737dSWaiman Long# not be included in the cpuset.cpus.isolated control file which contains
63572c6303aSWaiman Long# only CPUs in isolated partitions.
636105f3fe9SWaiman Long#
63772c6303aSWaiman Long# $1 - expected isolated cpu list(s) <isolcpus1>{,<isolcpus2>}
63872c6303aSWaiman Long# <isolcpus1> - expected sched/domains value
639877c737dSWaiman Long# <isolcpus2> - cpuset.cpus.isolated value = <isolcpus1> if not defined
640105f3fe9SWaiman Long#
641105f3fe9SWaiman Longcheck_isolcpus()
642105f3fe9SWaiman Long{
643105f3fe9SWaiman Long	EXPECT_VAL=$1
644105f3fe9SWaiman Long	ISOLCPUS=
645105f3fe9SWaiman Long	LASTISOLCPU=
646105f3fe9SWaiman Long	SCHED_DOMAINS=/sys/kernel/debug/sched/domains
647877c737dSWaiman Long	ISCPUS=${CGROUP2}/cpuset.cpus.isolated
64872c6303aSWaiman Long	if [[ $EXPECT_VAL = . ]]
64972c6303aSWaiman Long	then
65072c6303aSWaiman Long		EXPECT_VAL=
65172c6303aSWaiman Long		EXPECT_VAL2=
65272c6303aSWaiman Long	elif [[ $(expr $EXPECT_VAL : ".*,.*") > 0 ]]
65372c6303aSWaiman Long	then
65472c6303aSWaiman Long		set -- $(echo $EXPECT_VAL | sed -e "s/,/ /g")
65572c6303aSWaiman Long		EXPECT_VAL=$1
65672c6303aSWaiman Long		EXPECT_VAL2=$2
65772c6303aSWaiman Long	else
65872c6303aSWaiman Long		EXPECT_VAL2=$EXPECT_VAL
65972c6303aSWaiman Long	fi
66072c6303aSWaiman Long
66172c6303aSWaiman Long	#
66272c6303aSWaiman Long	# Check the debug isolated cpumask, if present
66372c6303aSWaiman Long	#
66472c6303aSWaiman Long	[[ -f $ISCPUS ]] && {
66572c6303aSWaiman Long		ISOLCPUS=$(cat $ISCPUS)
66672c6303aSWaiman Long		[[ "$EXPECT_VAL2" != "$ISOLCPUS" ]] && {
66772c6303aSWaiman Long			# Take a 50ms pause and try again
66872c6303aSWaiman Long			pause 0.05
66972c6303aSWaiman Long			ISOLCPUS=$(cat $ISCPUS)
67072c6303aSWaiman Long		}
67172c6303aSWaiman Long		[[ "$EXPECT_VAL2" != "$ISOLCPUS" ]] && return 1
67272c6303aSWaiman Long		ISOLCPUS=
67372c6303aSWaiman Long	}
67472c6303aSWaiman Long
67572c6303aSWaiman Long	#
67672c6303aSWaiman Long	# Use the sched domain in debugfs to check isolated CPUs, if available
67772c6303aSWaiman Long	#
678105f3fe9SWaiman Long	[[ -d $SCHED_DOMAINS ]] || return 0
679105f3fe9SWaiman Long
680105f3fe9SWaiman Long	for ((CPU=0; CPU < $NR_CPUS; CPU++))
681105f3fe9SWaiman Long	do
682105f3fe9SWaiman Long		[[ -n "$(ls ${SCHED_DOMAINS}/cpu$CPU)" ]] && continue
683105f3fe9SWaiman Long
684105f3fe9SWaiman Long		if [[ -z "$LASTISOLCPU" ]]
685105f3fe9SWaiman Long		then
686105f3fe9SWaiman Long			ISOLCPUS=$CPU
687105f3fe9SWaiman Long			LASTISOLCPU=$CPU
688105f3fe9SWaiman Long		elif [[ "$LASTISOLCPU" -eq $((CPU - 1)) ]]
689105f3fe9SWaiman Long		then
690105f3fe9SWaiman Long			echo $ISOLCPUS | grep -q "\<$LASTISOLCPU\$"
691105f3fe9SWaiman Long			if [[ $? -eq 0 ]]
692105f3fe9SWaiman Long			then
693105f3fe9SWaiman Long				ISOLCPUS=${ISOLCPUS}-
694105f3fe9SWaiman Long			fi
695105f3fe9SWaiman Long			LASTISOLCPU=$CPU
696105f3fe9SWaiman Long		else
697105f3fe9SWaiman Long			if [[ $ISOLCPUS = *- ]]
698105f3fe9SWaiman Long			then
699105f3fe9SWaiman Long				ISOLCPUS=${ISOLCPUS}$LASTISOLCPU
700105f3fe9SWaiman Long			fi
701105f3fe9SWaiman Long			ISOLCPUS=${ISOLCPUS},$CPU
702105f3fe9SWaiman Long			LASTISOLCPU=$CPU
703105f3fe9SWaiman Long		fi
704105f3fe9SWaiman Long	done
705105f3fe9SWaiman Long	[[ "$ISOLCPUS" = *- ]] && ISOLCPUS=${ISOLCPUS}$LASTISOLCPU
706105f3fe9SWaiman Long	[[ "$EXPECT_VAL" = "$ISOLCPUS" ]]
707105f3fe9SWaiman Long}
708105f3fe9SWaiman Long
709105f3fe9SWaiman Longtest_fail()
710105f3fe9SWaiman Long{
711105f3fe9SWaiman Long	TESTNUM=$1
712105f3fe9SWaiman Long	TESTTYPE=$2
713105f3fe9SWaiman Long	ADDINFO=$3
714105f3fe9SWaiman Long	echo "Test $TEST[$TESTNUM] failed $TESTTYPE check!"
715105f3fe9SWaiman Long	[[ -n "$ADDINFO" ]] && echo "*** $ADDINFO ***"
716105f3fe9SWaiman Long	eval echo \${$TEST[$I]}
717105f3fe9SWaiman Long	echo
718105f3fe9SWaiman Long	dump_states
719105f3fe9SWaiman Long	exit 1
720105f3fe9SWaiman Long}
721105f3fe9SWaiman Long
722105f3fe9SWaiman Long#
72372c6303aSWaiman Long# Check to see if there are unexpected isolated CPUs left
72472c6303aSWaiman Long#
72572c6303aSWaiman Longnull_isolcpus_check()
72672c6303aSWaiman Long{
72772c6303aSWaiman Long	[[ $VERBOSE -gt 0 ]] || return 0
728877c737dSWaiman Long	# Retry a few times before printing error
729877c737dSWaiman Long	RETRY=0
73043ee4014SWaiman Long	while [[ $RETRY -lt 8 ]]
731877c737dSWaiman Long	do
73243ee4014SWaiman Long		pause 0.02
73372c6303aSWaiman Long		check_isolcpus "."
734877c737dSWaiman Long		[[ $? -eq 0 ]] && return 0
735877c737dSWaiman Long		((RETRY++))
736877c737dSWaiman Long	done
73772c6303aSWaiman Long	echo "Unexpected isolated CPUs: $ISOLCPUS"
73872c6303aSWaiman Long	dump_states
73972c6303aSWaiman Long	exit 1
74072c6303aSWaiman Long}
74172c6303aSWaiman Long
74272c6303aSWaiman Long#
743a8c52ebaSWaiman Long# Run cpuset state transition test
744a8c52ebaSWaiman Long#  $1 - test matrix name
745a8c52ebaSWaiman Long#
746a8c52ebaSWaiman Long# This test is somewhat fragile as delays (sleep x) are added in various
747a8c52ebaSWaiman Long# places to make sure state changes are fully propagated before the next
748a8c52ebaSWaiman Long# action. These delays may need to be adjusted if running in a slower machine.
749a8c52ebaSWaiman Long#
750a8c52ebaSWaiman Longrun_state_test()
751a8c52ebaSWaiman Long{
752a8c52ebaSWaiman Long	TEST=$1
753a8c52ebaSWaiman Long	CONTROLLER=cpuset
754a8c52ebaSWaiman Long	I=0
755a8c52ebaSWaiman Long	eval CNT="\${#$TEST[@]}"
756a8c52ebaSWaiman Long
757a8c52ebaSWaiman Long	reset_cgroup_states
758a8c52ebaSWaiman Long	console_msg "Running state transition test ..."
759a8c52ebaSWaiman Long
760a8c52ebaSWaiman Long	while [[ $I -lt $CNT ]]
761a8c52ebaSWaiman Long	do
76243ee4014SWaiman Long		echo "Running test $I ..." > $CONSOLE
763105f3fe9SWaiman Long		[[ $VERBOSE -gt 1 ]] && {
764105f3fe9SWaiman Long			echo ""
765105f3fe9SWaiman Long			eval echo \${$TEST[$I]}
766105f3fe9SWaiman Long		}
767a8c52ebaSWaiman Long		eval set -- "\${$TEST[$I]}"
768105f3fe9SWaiman Long		OLD_A1=$1
769105f3fe9SWaiman Long		OLD_A2=$2
770105f3fe9SWaiman Long		OLD_A3=$3
771105f3fe9SWaiman Long		OLD_B1=$4
772105f3fe9SWaiman Long		NEW_A1=$5
773105f3fe9SWaiman Long		NEW_A2=$6
774105f3fe9SWaiman Long		NEW_A3=$7
775105f3fe9SWaiman Long		NEW_B1=$8
776105f3fe9SWaiman Long		RESULT=$9
777105f3fe9SWaiman Long		ECPUS=${10}
778105f3fe9SWaiman Long		STATES=${11}
779105f3fe9SWaiman Long		ICPUS=${12}
780a8c52ebaSWaiman Long
781105f3fe9SWaiman Long		set_ctrl_state_noerr B1       $OLD_B1
782a8c52ebaSWaiman Long		set_ctrl_state_noerr A1       $OLD_A1
783a8c52ebaSWaiman Long		set_ctrl_state_noerr A1/A2    $OLD_A2
784a8c52ebaSWaiman Long		set_ctrl_state_noerr A1/A2/A3 $OLD_A3
785a8c52ebaSWaiman Long		RETVAL=0
786a8c52ebaSWaiman Long		set_ctrl_state A1       $NEW_A1; ((RETVAL += $?))
787a8c52ebaSWaiman Long		set_ctrl_state A1/A2    $NEW_A2; ((RETVAL += $?))
788a8c52ebaSWaiman Long		set_ctrl_state A1/A2/A3 $NEW_A3; ((RETVAL += $?))
789a8c52ebaSWaiman Long		set_ctrl_state B1       $NEW_B1; ((RETVAL += $?))
790a8c52ebaSWaiman Long
791105f3fe9SWaiman Long		[[ $RETVAL -ne $RESULT ]] && test_fail $I result
792a8c52ebaSWaiman Long
793a8c52ebaSWaiman Long		[[ -n "$ECPUS" && "$ECPUS" != . ]] && {
794a8c52ebaSWaiman Long			check_effective_cpus $ECPUS
795105f3fe9SWaiman Long			[[ $? -ne 0 ]] && test_fail $I "effective CPU"
796a8c52ebaSWaiman Long		}
797a8c52ebaSWaiman Long
798105f3fe9SWaiman Long		[[ -n "$STATES" && "$STATES" != . ]] && {
799a8c52ebaSWaiman Long			check_cgroup_states $STATES
800105f3fe9SWaiman Long			[[ $? -ne 0 ]] && test_fail $I states
801a8c52ebaSWaiman Long		}
802a8c52ebaSWaiman Long
803105f3fe9SWaiman Long		# Compare the expected isolated CPUs with the actual ones,
804105f3fe9SWaiman Long		# if available
805105f3fe9SWaiman Long		[[ -n "$ICPUS" ]] && {
806105f3fe9SWaiman Long			check_isolcpus $ICPUS
807105f3fe9SWaiman Long			[[ $? -ne 0 ]] && test_fail $I "isolated CPU" \
808105f3fe9SWaiman Long				"Expect $ICPUS, get $ISOLCPUS instead"
809105f3fe9SWaiman Long		}
810a8c52ebaSWaiman Long		reset_cgroup_states
811a8c52ebaSWaiman Long		#
812a8c52ebaSWaiman Long		# Check to see if effective cpu list changes
813a8c52ebaSWaiman Long		#
814a8c52ebaSWaiman Long		NEWLIST=$(cat cpuset.cpus.effective)
815105f3fe9SWaiman Long		RETRY=0
816877c737dSWaiman Long		while [[ $NEWLIST != $CPULIST && $RETRY -lt 8 ]]
817105f3fe9SWaiman Long		do
818105f3fe9SWaiman Long			# Wait a bit longer & recheck a few times
81943ee4014SWaiman Long			pause 0.02
820105f3fe9SWaiman Long			((RETRY++))
821105f3fe9SWaiman Long			NEWLIST=$(cat cpuset.cpus.effective)
822105f3fe9SWaiman Long		done
823a8c52ebaSWaiman Long		[[ $NEWLIST != $CPULIST ]] && {
824a8c52ebaSWaiman Long			echo "Effective cpus changed to $NEWLIST after test $I!"
825a8c52ebaSWaiman Long			exit 1
826a8c52ebaSWaiman Long		}
82772c6303aSWaiman Long		null_isolcpus_check
828105f3fe9SWaiman Long		[[ $VERBOSE -gt 0 ]] && echo "Test $I done."
829a8c52ebaSWaiman Long		((I++))
830a8c52ebaSWaiman Long	done
831a8c52ebaSWaiman Long	echo "All $I tests of $TEST PASSED."
832a8c52ebaSWaiman Long}
833a8c52ebaSWaiman Long
834a8c52ebaSWaiman Long#
83514060dfcSWaiman Long# Testing the new "isolated" partition root type
83614060dfcSWaiman Long#
83714060dfcSWaiman Longtest_isolated()
83814060dfcSWaiman Long{
83914060dfcSWaiman Long	cd $CGROUP2/test
84014060dfcSWaiman Long	echo 2-3 > cpuset.cpus
84114060dfcSWaiman Long	TYPE=$(cat cpuset.cpus.partition)
84214060dfcSWaiman Long	[[ $TYPE = member ]] || echo member > cpuset.cpus.partition
84314060dfcSWaiman Long
84414060dfcSWaiman Long	console_msg "Change from member to root"
84514060dfcSWaiman Long	test_partition root
84614060dfcSWaiman Long
84714060dfcSWaiman Long	console_msg "Change from root to isolated"
84814060dfcSWaiman Long	test_partition isolated
84914060dfcSWaiman Long
85014060dfcSWaiman Long	console_msg "Change from isolated to member"
85114060dfcSWaiman Long	test_partition member
85214060dfcSWaiman Long
85314060dfcSWaiman Long	console_msg "Change from member to isolated"
85414060dfcSWaiman Long	test_partition isolated
85514060dfcSWaiman Long
85614060dfcSWaiman Long	console_msg "Change from isolated to root"
85714060dfcSWaiman Long	test_partition root
85814060dfcSWaiman Long
85914060dfcSWaiman Long	console_msg "Change from root to member"
86014060dfcSWaiman Long	test_partition member
86114060dfcSWaiman Long
86214060dfcSWaiman Long	#
86314060dfcSWaiman Long	# Testing partition root with no cpu
86414060dfcSWaiman Long	#
86514060dfcSWaiman Long	console_msg "Distribute all cpus to child partition"
86614060dfcSWaiman Long	echo +cpuset > cgroup.subtree_control
86714060dfcSWaiman Long	test_partition root
86814060dfcSWaiman Long
86914060dfcSWaiman Long	mkdir A1
87014060dfcSWaiman Long	cd A1
87114060dfcSWaiman Long	echo 2-3 > cpuset.cpus
87214060dfcSWaiman Long	test_partition root
87314060dfcSWaiman Long	test_effective_cpus 2-3
87414060dfcSWaiman Long	cd ..
87514060dfcSWaiman Long	test_effective_cpus ""
87614060dfcSWaiman Long
87714060dfcSWaiman Long	console_msg "Moving task to partition test"
87814060dfcSWaiman Long	test_add_proc "No space left"
87914060dfcSWaiman Long	cd A1
88014060dfcSWaiman Long	test_add_proc ""
88114060dfcSWaiman Long	cd ..
88214060dfcSWaiman Long
88314060dfcSWaiman Long	console_msg "Shrink and expand child partition"
88414060dfcSWaiman Long	cd A1
88514060dfcSWaiman Long	echo 2 > cpuset.cpus
88614060dfcSWaiman Long	cd ..
88714060dfcSWaiman Long	test_effective_cpus 3
88814060dfcSWaiman Long	cd A1
88914060dfcSWaiman Long	echo 2-3 > cpuset.cpus
89014060dfcSWaiman Long	cd ..
89114060dfcSWaiman Long	test_effective_cpus ""
89214060dfcSWaiman Long
89314060dfcSWaiman Long	# Cleaning up
89414060dfcSWaiman Long	console_msg "Cleaning up"
89514060dfcSWaiman Long	echo $$ > $CGROUP2/cgroup.procs
89614060dfcSWaiman Long	[[ -d A1 ]] && rmdir A1
89772c6303aSWaiman Long	null_isolcpus_check
89814060dfcSWaiman Long}
89914060dfcSWaiman Long
90014060dfcSWaiman Long#
901a8c52ebaSWaiman Long# Wait for inotify event for the given file and read it
902a8c52ebaSWaiman Long# $1: cgroup file to wait for
903a8c52ebaSWaiman Long# $2: file to store the read result
904a8c52ebaSWaiman Long#
905a8c52ebaSWaiman Longwait_inotify()
906a8c52ebaSWaiman Long{
907a8c52ebaSWaiman Long	CGROUP_FILE=$1
908a8c52ebaSWaiman Long	OUTPUT_FILE=$2
909a8c52ebaSWaiman Long
910a8c52ebaSWaiman Long	$WAIT_INOTIFY $CGROUP_FILE
911a8c52ebaSWaiman Long	cat $CGROUP_FILE > $OUTPUT_FILE
912a8c52ebaSWaiman Long}
913a8c52ebaSWaiman Long
914a8c52ebaSWaiman Long#
915a8c52ebaSWaiman Long# Test if inotify events are properly generated when going into and out of
916a8c52ebaSWaiman Long# invalid partition state.
917a8c52ebaSWaiman Long#
918a8c52ebaSWaiman Longtest_inotify()
919a8c52ebaSWaiman Long{
920a8c52ebaSWaiman Long	ERR=0
921a8c52ebaSWaiman Long	PRS=/tmp/.prs_$$
922105f3fe9SWaiman Long	cd $CGROUP2/test
923a8c52ebaSWaiman Long	[[ -f $WAIT_INOTIFY ]] || {
924a8c52ebaSWaiman Long		echo "wait_inotify not found, inotify test SKIPPED."
925a8c52ebaSWaiman Long		return
926a8c52ebaSWaiman Long	}
927a8c52ebaSWaiman Long
928a8c52ebaSWaiman Long	pause 0.01
929a8c52ebaSWaiman Long	echo 1 > cpuset.cpus
930a8c52ebaSWaiman Long	echo 0 > cgroup.procs
931a8c52ebaSWaiman Long	echo root > cpuset.cpus.partition
932a8c52ebaSWaiman Long	pause 0.01
933a8c52ebaSWaiman Long	rm -f $PRS
934a8c52ebaSWaiman Long	wait_inotify $PWD/cpuset.cpus.partition $PRS &
935a8c52ebaSWaiman Long	pause 0.01
936105f3fe9SWaiman Long	set_ctrl_state . "O1=0"
937a8c52ebaSWaiman Long	pause 0.01
938a8c52ebaSWaiman Long	check_cgroup_states ".:P-1"
939a8c52ebaSWaiman Long	if [[ $? -ne 0 ]]
940a8c52ebaSWaiman Long	then
941a8c52ebaSWaiman Long		echo "FAILED: Inotify test - partition not invalid"
942a8c52ebaSWaiman Long		ERR=1
943a8c52ebaSWaiman Long	elif [[ ! -f $PRS ]]
944a8c52ebaSWaiman Long	then
945a8c52ebaSWaiman Long		echo "FAILED: Inotify test - event not generated"
946a8c52ebaSWaiman Long		ERR=1
947a8c52ebaSWaiman Long		kill %1
948a8c52ebaSWaiman Long	elif [[ $(cat $PRS) != "root invalid"* ]]
949a8c52ebaSWaiman Long	then
950a8c52ebaSWaiman Long		echo "FAILED: Inotify test - incorrect state"
951a8c52ebaSWaiman Long		cat $PRS
952a8c52ebaSWaiman Long		ERR=1
953a8c52ebaSWaiman Long	fi
954a8c52ebaSWaiman Long	online_cpus
955a8c52ebaSWaiman Long	echo member > cpuset.cpus.partition
956a8c52ebaSWaiman Long	echo 0 > ../cgroup.procs
957a8c52ebaSWaiman Long	if [[ $ERR -ne 0 ]]
958a8c52ebaSWaiman Long	then
959a8c52ebaSWaiman Long		exit 1
960a8c52ebaSWaiman Long	else
961a8c52ebaSWaiman Long		echo "Inotify test PASSED"
962a8c52ebaSWaiman Long	fi
963a8c52ebaSWaiman Long}
964a8c52ebaSWaiman Long
9651e85591dSKamalesh Babulaltrap cleanup 0 2 3 6
966a8c52ebaSWaiman Longrun_state_test TEST_MATRIX
967a8c52ebaSWaiman Longtest_isolated
968a8c52ebaSWaiman Longtest_inotify
969a8c52ebaSWaiman Longecho "All tests PASSED."
970