xref: /linux/tools/testing/selftests/cgroup/test_cpuset_prs.sh (revision 1e85591db11b7ac097a1b34887c682e6353798c4)
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#
6a8c52ebaSWaiman Long# The sched verbose flag is set, if available, 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"
13a8c52ebaSWaiman Long	exit 0
14a8c52ebaSWaiman Long}
15a8c52ebaSWaiman Long
16a8c52ebaSWaiman Long[[ $(id -u) -eq 0 ]] || skip_test "Test must be run as root!"
17a8c52ebaSWaiman Long
18a8c52ebaSWaiman Long# Set sched verbose flag, if available
19*1e85591dSKamalesh Babulalif [[ -d /sys/kernel/debug/sched ]]
20*1e85591dSKamalesh Babulalthen
21*1e85591dSKamalesh Babulal	# Used to restore the original setting during cleanup
22*1e85591dSKamalesh Babulal	SCHED_DEBUG=$(cat /sys/kernel/debug/sched/verbose)
23*1e85591dSKamalesh Babulal	echo Y > /sys/kernel/debug/sched/verbose
24*1e85591dSKamalesh Babulalfi
25a8c52ebaSWaiman Long
26a8c52ebaSWaiman Long# Get wait_inotify location
27a8c52ebaSWaiman LongWAIT_INOTIFY=$(cd $(dirname $0); pwd)/wait_inotify
28a8c52ebaSWaiman Long
29a8c52ebaSWaiman Long# Find cgroup v2 mount point
30a8c52ebaSWaiman LongCGROUP2=$(mount -t cgroup2 | head -1 | awk -e '{print $3}')
31a8c52ebaSWaiman Long[[ -n "$CGROUP2" ]] || skip_test "Cgroup v2 mount point not found!"
32a8c52ebaSWaiman Long
3335b7fa4eSBreno LeitaoCPUS=$(lscpu | grep "^CPU(s):" | sed -e "s/.*:[[:space:]]*//")
34a8c52ebaSWaiman Long[[ $CPUS -lt 8 ]] && skip_test "Test needs at least 8 cpus available!"
35a8c52ebaSWaiman Long
36a8c52ebaSWaiman Long# Set verbose flag and delay factor
37a8c52ebaSWaiman LongPROG=$1
38a8c52ebaSWaiman LongVERBOSE=
39a8c52ebaSWaiman LongDELAY_FACTOR=1
40a8c52ebaSWaiman Longwhile [[ "$1" = -* ]]
41a8c52ebaSWaiman Longdo
42a8c52ebaSWaiman Long	case "$1" in
43a8c52ebaSWaiman Long		-v) VERBOSE=1
44a8c52ebaSWaiman Long		    break
45a8c52ebaSWaiman Long		    ;;
46a8c52ebaSWaiman Long		-d) DELAY_FACTOR=$2
47a8c52ebaSWaiman Long		    shift
48a8c52ebaSWaiman Long		    break
49a8c52ebaSWaiman Long		    ;;
50a8c52ebaSWaiman Long		*)  echo "Usage: $PROG [-v] [-d <delay-factor>"
51a8c52ebaSWaiman Long		    exit
52a8c52ebaSWaiman Long		    ;;
53a8c52ebaSWaiman Long	esac
54a8c52ebaSWaiman Long	shift
55a8c52ebaSWaiman Longdone
56a8c52ebaSWaiman Long
57a8c52ebaSWaiman Longcd $CGROUP2
58a8c52ebaSWaiman Longecho +cpuset > cgroup.subtree_control
59a8c52ebaSWaiman Long[[ -d test ]] || mkdir test
60a8c52ebaSWaiman Longcd test
61a8c52ebaSWaiman Long
62*1e85591dSKamalesh Babulalcleanup()
63*1e85591dSKamalesh Babulal{
64*1e85591dSKamalesh Babulal	online_cpus
65*1e85591dSKamalesh Babulal	rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1
66*1e85591dSKamalesh Babulal	cd ..
67*1e85591dSKamalesh Babulal	rmdir test > /dev/null 2>&1
68*1e85591dSKamalesh Babulal	echo "$SCHED_DEBUG" > /sys/kernel/debug/sched/verbose
69*1e85591dSKamalesh Babulal}
70*1e85591dSKamalesh Babulal
71a8c52ebaSWaiman Long# Pause in ms
72a8c52ebaSWaiman Longpause()
73a8c52ebaSWaiman Long{
74a8c52ebaSWaiman Long	DELAY=$1
75a8c52ebaSWaiman Long	LOOP=0
76a8c52ebaSWaiman Long	while [[ $LOOP -lt $DELAY_FACTOR ]]
77a8c52ebaSWaiman Long	do
78a8c52ebaSWaiman Long		sleep $DELAY
79a8c52ebaSWaiman Long		((LOOP++))
80a8c52ebaSWaiman Long	done
81a8c52ebaSWaiman Long	return 0
82a8c52ebaSWaiman Long}
83a8c52ebaSWaiman Long
84a8c52ebaSWaiman Longconsole_msg()
85a8c52ebaSWaiman Long{
86a8c52ebaSWaiman Long	MSG=$1
87a8c52ebaSWaiman Long	echo "$MSG"
88a8c52ebaSWaiman Long	echo "" > /dev/console
89a8c52ebaSWaiman Long	echo "$MSG" > /dev/console
90a8c52ebaSWaiman Long	pause 0.01
91a8c52ebaSWaiman Long}
92a8c52ebaSWaiman Long
93a8c52ebaSWaiman Longtest_partition()
94a8c52ebaSWaiman Long{
95a8c52ebaSWaiman Long	EXPECTED_VAL=$1
96a8c52ebaSWaiman Long	echo $EXPECTED_VAL > cpuset.cpus.partition
97a8c52ebaSWaiman Long	[[ $? -eq 0 ]] || exit 1
98a8c52ebaSWaiman Long	ACTUAL_VAL=$(cat cpuset.cpus.partition)
99a8c52ebaSWaiman Long	[[ $ACTUAL_VAL != $EXPECTED_VAL ]] && {
100a8c52ebaSWaiman Long		echo "cpuset.cpus.partition: expect $EXPECTED_VAL, found $EXPECTED_VAL"
101a8c52ebaSWaiman Long		echo "Test FAILED"
102a8c52ebaSWaiman Long		exit 1
103a8c52ebaSWaiman Long	}
104a8c52ebaSWaiman Long}
105a8c52ebaSWaiman Long
106a8c52ebaSWaiman Longtest_effective_cpus()
107a8c52ebaSWaiman Long{
108a8c52ebaSWaiman Long	EXPECTED_VAL=$1
109a8c52ebaSWaiman Long	ACTUAL_VAL=$(cat cpuset.cpus.effective)
110a8c52ebaSWaiman Long	[[ "$ACTUAL_VAL" != "$EXPECTED_VAL" ]] && {
111a8c52ebaSWaiman Long		echo "cpuset.cpus.effective: expect '$EXPECTED_VAL', found '$EXPECTED_VAL'"
112a8c52ebaSWaiman Long		echo "Test FAILED"
113a8c52ebaSWaiman Long		exit 1
114a8c52ebaSWaiman Long	}
115a8c52ebaSWaiman Long}
116a8c52ebaSWaiman Long
117a8c52ebaSWaiman Long# Adding current process to cgroup.procs as a test
118a8c52ebaSWaiman Longtest_add_proc()
119a8c52ebaSWaiman Long{
120a8c52ebaSWaiman Long	OUTSTR="$1"
121a8c52ebaSWaiman Long	ERRMSG=$((echo $$ > cgroup.procs) |& cat)
122a8c52ebaSWaiman Long	echo $ERRMSG | grep -q "$OUTSTR"
123a8c52ebaSWaiman Long	[[ $? -ne 0 ]] && {
124a8c52ebaSWaiman Long		echo "cgroup.procs: expect '$OUTSTR', got '$ERRMSG'"
125a8c52ebaSWaiman Long		echo "Test FAILED"
126a8c52ebaSWaiman Long		exit 1
127a8c52ebaSWaiman Long	}
128a8c52ebaSWaiman Long	echo $$ > $CGROUP2/cgroup.procs	# Move out the task
129a8c52ebaSWaiman Long}
130a8c52ebaSWaiman Long
131a8c52ebaSWaiman Long#
132a8c52ebaSWaiman Long# Testing the new "isolated" partition root type
133a8c52ebaSWaiman Long#
134a8c52ebaSWaiman Longtest_isolated()
135a8c52ebaSWaiman Long{
136a8c52ebaSWaiman Long	echo 2-3 > cpuset.cpus
137a8c52ebaSWaiman Long	TYPE=$(cat cpuset.cpus.partition)
138a8c52ebaSWaiman Long	[[ $TYPE = member ]] || echo member > cpuset.cpus.partition
139a8c52ebaSWaiman Long
140a8c52ebaSWaiman Long	console_msg "Change from member to root"
141a8c52ebaSWaiman Long	test_partition root
142a8c52ebaSWaiman Long
143a8c52ebaSWaiman Long	console_msg "Change from root to isolated"
144a8c52ebaSWaiman Long	test_partition isolated
145a8c52ebaSWaiman Long
146a8c52ebaSWaiman Long	console_msg "Change from isolated to member"
147a8c52ebaSWaiman Long	test_partition member
148a8c52ebaSWaiman Long
149a8c52ebaSWaiman Long	console_msg "Change from member to isolated"
150a8c52ebaSWaiman Long	test_partition isolated
151a8c52ebaSWaiman Long
152a8c52ebaSWaiman Long	console_msg "Change from isolated to root"
153a8c52ebaSWaiman Long	test_partition root
154a8c52ebaSWaiman Long
155a8c52ebaSWaiman Long	console_msg "Change from root to member"
156a8c52ebaSWaiman Long	test_partition member
157a8c52ebaSWaiman Long
158a8c52ebaSWaiman Long	#
159a8c52ebaSWaiman Long	# Testing partition root with no cpu
160a8c52ebaSWaiman Long	#
161a8c52ebaSWaiman Long	console_msg "Distribute all cpus to child partition"
162a8c52ebaSWaiman Long	echo +cpuset > cgroup.subtree_control
163a8c52ebaSWaiman Long	test_partition root
164a8c52ebaSWaiman Long
165a8c52ebaSWaiman Long	mkdir A1
166a8c52ebaSWaiman Long	cd A1
167a8c52ebaSWaiman Long	echo 2-3 > cpuset.cpus
168a8c52ebaSWaiman Long	test_partition root
169a8c52ebaSWaiman Long	test_effective_cpus 2-3
170a8c52ebaSWaiman Long	cd ..
171a8c52ebaSWaiman Long	test_effective_cpus ""
172a8c52ebaSWaiman Long
173a8c52ebaSWaiman Long	console_msg "Moving task to partition test"
174a8c52ebaSWaiman Long	test_add_proc "No space left"
175a8c52ebaSWaiman Long	cd A1
176a8c52ebaSWaiman Long	test_add_proc ""
177a8c52ebaSWaiman Long	cd ..
178a8c52ebaSWaiman Long
179a8c52ebaSWaiman Long	console_msg "Shrink and expand child partition"
180a8c52ebaSWaiman Long	cd A1
181a8c52ebaSWaiman Long	echo 2 > cpuset.cpus
182a8c52ebaSWaiman Long	cd ..
183a8c52ebaSWaiman Long	test_effective_cpus 3
184a8c52ebaSWaiman Long	cd A1
185a8c52ebaSWaiman Long	echo 2-3 > cpuset.cpus
186a8c52ebaSWaiman Long	cd ..
187a8c52ebaSWaiman Long	test_effective_cpus ""
188a8c52ebaSWaiman Long
189a8c52ebaSWaiman Long	# Cleaning up
190a8c52ebaSWaiman Long	console_msg "Cleaning up"
191a8c52ebaSWaiman Long	echo $$ > $CGROUP2/cgroup.procs
192a8c52ebaSWaiman Long	[[ -d A1 ]] && rmdir A1
193a8c52ebaSWaiman Long}
194a8c52ebaSWaiman Long
195a8c52ebaSWaiman Long#
196a8c52ebaSWaiman Long# Cpuset controller state transition test matrix.
197a8c52ebaSWaiman Long#
198a8c52ebaSWaiman Long# Cgroup test hierarchy
199a8c52ebaSWaiman Long#
200a8c52ebaSWaiman Long# test -- A1 -- A2 -- A3
201a8c52ebaSWaiman Long#      \- B1
202a8c52ebaSWaiman Long#
203a8c52ebaSWaiman Long#  P<v> = set cpus.partition (0:member, 1:root, 2:isolated, -1:root invalid)
204a8c52ebaSWaiman Long#  C<l> = add cpu-list
205a8c52ebaSWaiman Long#  S<p> = use prefix in subtree_control
206a8c52ebaSWaiman Long#  T    = put a task into cgroup
207a8c52ebaSWaiman Long#  O<c>-<v> = Write <v> to CPU online file of <c>
208a8c52ebaSWaiman Long#
209a8c52ebaSWaiman LongSETUP_A123_PARTITIONS="C1-3:P1:S+ C2-3:P1:S+ C3:P1"
210a8c52ebaSWaiman LongTEST_MATRIX=(
211a8c52ebaSWaiman Long	# test  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate
212a8c52ebaSWaiman Long	# ----  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------
213a8c52ebaSWaiman Long	"  S+    C0-1     .      .    C2-3    S+    C4-5     .      .     0 A2:0-1"
214a8c52ebaSWaiman Long	"  S+    C0-1     .      .    C2-3    P1      .      .      .     0 "
215a8c52ebaSWaiman Long	"  S+    C0-1     .      .    C2-3   P1:S+ C0-1:P1   .      .     0 "
216a8c52ebaSWaiman Long	"  S+    C0-1     .      .    C2-3   P1:S+  C1:P1    .      .     0 "
217a8c52ebaSWaiman Long	"  S+   C0-1:S+   .      .    C2-3     .      .      .     P1     0 "
218a8c52ebaSWaiman Long	"  S+   C0-1:P1   .      .    C2-3    S+     C1      .      .     0 "
219a8c52ebaSWaiman Long	"  S+   C0-1:P1   .      .    C2-3    S+    C1:P1    .      .     0 "
220a8c52ebaSWaiman Long	"  S+   C0-1:P1   .      .    C2-3    S+    C1:P1    .     P1     0 "
221a8c52ebaSWaiman Long	"  S+   C0-1:P1   .      .    C2-3   C4-5     .      .      .     0 A1:4-5"
222a8c52ebaSWaiman Long	"  S+   C0-1:P1   .      .    C2-3  S+:C4-5   .      .      .     0 A1:4-5"
223a8c52ebaSWaiman Long	"  S+    C0-1     .      .   C2-3:P1   .      .      .     C2     0 "
224a8c52ebaSWaiman Long	"  S+    C0-1     .      .   C2-3:P1   .      .      .    C4-5    0 B1:4-5"
225a8c52ebaSWaiman Long	"  S+ C0-3:P1:S+ C2-3:P1 .      .      .      .      .      .     0 A1:0-1,A2:2-3"
226a8c52ebaSWaiman Long	"  S+ C0-3:P1:S+ C2-3:P1 .      .     C1-3    .      .      .     0 A1:1,A2:2-3"
227a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .     C3      .      .      .     0 A1:,A2:3 A1:P1,A2:P1"
228a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .     C3      P0     .      .     0 A1:3,A2:3 A1:P1,A2:P0"
229a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C2:P1  .      .     C2-4    .      .      .     0 A1:3-4,A2:2"
230a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .     C3      .      .     C0-2   0 A1:,B1:0-2 A1:P1,A2:P1"
231a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .     C2-3    .      .      .     0 A1:,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
232a8c52ebaSWaiman Long
233a8c52ebaSWaiman Long	# CPU offlining cases:
234a8c52ebaSWaiman Long	"  S+    C0-1     .      .    C2-3    S+    C4-5     .     O2-0   0 A1:0-1,B1:3"
235a8c52ebaSWaiman Long	"  S+ C0-3:P1:S+ C2-3:P1 .      .     O2-0    .      .      .     0 A1:0-1,A2:3"
236a8c52ebaSWaiman Long	"  S+ C0-3:P1:S+ C2-3:P1 .      .     O2-0   O2-1    .      .     0 A1:0-1,A2:2-3"
237a8c52ebaSWaiman Long	"  S+ C0-3:P1:S+ C2-3:P1 .      .     O1-0    .      .      .     0 A1:0,A2:2-3"
238a8c52ebaSWaiman Long	"  S+ C0-3:P1:S+ C2-3:P1 .      .     O1-0   O1-1    .      .     0 A1:0-1,A2:2-3"
239a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .     O3-0   O3-1    .      .     0 A1:2,A2:3 A1:P1,A2:P1"
240a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P2  .      .     O3-0   O3-1    .      .     0 A1:2,A2:3 A1:P1,A2:P2"
241a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .     O2-0   O2-1    .      .     0 A1:2,A2:3 A1:P1,A2:P1"
242a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P2  .      .     O2-0   O2-1    .      .     0 A1:2,A2:3 A1:P1,A2:P2"
243a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .     O2-0    .      .      .     0 A1:,A2:3 A1:P1,A2:P1"
244a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .     O3-0    .      .      .     0 A1:2,A2: A1:P1,A2:P1"
245a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .    T:O2-0   .      .      .     0 A1:3,A2:3 A1:P1,A2:P-1"
246a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .      .    T:O3-0   .      .     0 A1:2,A2:2 A1:P1,A2:P-1"
247a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .     O1-0    .      .      .     0 A1:,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
248a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .     O2-0    .      .      .     0 A1:1,A2:,A3:3 A1:P1,A2:P1,A3:P1"
249a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .     O3-0    .      .      .     0 A1:1,A2:2,A3: A1:P1,A2:P1,A3:P1"
250a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .    T:O1-0   .      .      .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1"
251a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .      .    T:O2-0   .      .     0 A1:1,A2:3,A3:3 A1:P1,A2:P1,A3:P-1"
252a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .      .      .    T:O3-0   .     0 A1:1,A2:2,A3:2 A1:P1,A2:P1,A3:P-1"
253a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .    T:O1-0  O1-1    .      .     0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
254a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .      .    T:O2-0  O2-1    .     0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
255a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .      .      .    T:O3-0  O3-1   0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
256a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .    T:O1-0  O2-0   O1-1    .     0 A1:1,A2:,A3:3 A1:P1,A2:P1,A3:P1"
257a8c52ebaSWaiman Long	"  S+ $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"
258a8c52ebaSWaiman Long
259a8c52ebaSWaiman Long	# test  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate
260a8c52ebaSWaiman Long	# ----  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------
261a8c52ebaSWaiman Long	#
262a8c52ebaSWaiman Long	# Incorrect change to cpuset.cpus invalidates partition root
263a8c52ebaSWaiman Long	#
264a8c52ebaSWaiman Long	# Adding CPUs to partition root that are not in parent's
265a8c52ebaSWaiman Long	# cpuset.cpus is allowed, but those extra CPUs are ignored.
266a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+ C3:P1   .      .      .     C2-4    .      .     0 A1:,A2:2-3 A1:P1,A2:P1"
267a8c52ebaSWaiman Long
268a8c52ebaSWaiman Long	# Taking away all CPUs from parent or itself if there are tasks
269a8c52ebaSWaiman Long	# will make the partition invalid.
270a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .      T     C2-3    .      .     0 A1:2-3,A2:2-3 A1:P1,A2:P-1"
271a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .    T:C2-3   .      .      .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1"
272a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    . T:C2-3:C1-3 .      .      .     0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
273a8c52ebaSWaiman Long
274a8c52ebaSWaiman Long	# Changing a partition root to member makes child partitions invalid
275a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .      P0     .      .      .     0 A1:2-3,A2:3 A1:P0,A2:P-1"
276a8c52ebaSWaiman Long	"  S+ $SETUP_A123_PARTITIONS    .     C2-3    P0     .      .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P0,A3:P-1"
277a8c52ebaSWaiman Long
278a8c52ebaSWaiman Long	# cpuset.cpus can contains cpus not in parent's cpuset.cpus as long
279a8c52ebaSWaiman Long	# as they overlap.
280a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  .      .      .      .   C3-4:P1   .      .     0 A1:2,A2:3 A1:P1,A2:P1"
281a8c52ebaSWaiman Long
282a8c52ebaSWaiman Long	# Deletion of CPUs distributed to child cgroup is allowed.
283a8c52ebaSWaiman Long	"  S+ C0-1:P1:S+ C1      .    C2-3   C4-5     .      .      .     0 A1:4-5,A2:4-5"
284a8c52ebaSWaiman Long
285a8c52ebaSWaiman Long	# To become a valid partition root, cpuset.cpus must overlap parent's
286a8c52ebaSWaiman Long	# cpuset.cpus.
287a8c52ebaSWaiman Long	"  S+   C0-1:P1   .      .    C2-3    S+   C4-5:P1   .      .     0 A1:0-1,A2:0-1 A1:P1,A2:P-1"
288a8c52ebaSWaiman Long
289a8c52ebaSWaiman Long	# Enabling partition with child cpusets is allowed
290a8c52ebaSWaiman Long	"  S+   C0-1:S+  C1      .    C2-3    P1      .      .      .     0 A1:0-1,A2:1 A1:P1"
291a8c52ebaSWaiman Long
292a8c52ebaSWaiman Long	# A partition root with non-partition root parent is invalid, but it
293a8c52ebaSWaiman Long	# can be made valid if its parent becomes a partition root too.
294a8c52ebaSWaiman Long	"  S+   C0-1:S+  C1      .    C2-3     .      P2     .      .     0 A1:0-1,A2:1 A1:P0,A2:P-2"
295a8c52ebaSWaiman Long	"  S+   C0-1:S+ C1:P2    .    C2-3     P1     .      .      .     0 A1:0,A2:1 A1:P1,A2:P2"
296a8c52ebaSWaiman Long
297a8c52ebaSWaiman Long	# A non-exclusive cpuset.cpus change will invalidate partition and its siblings
298a8c52ebaSWaiman Long	"  S+   C0-1:P1   .      .    C2-3   C0-2     .      .      .     0 A1:0-2,B1:2-3 A1:P-1,B1:P0"
299a8c52ebaSWaiman Long	"  S+   C0-1:P1   .      .  P1:C2-3  C0-2   .      .      .     0 A1:0-2,B1:2-3 A1:P-1,B1:P-1"
300a8c52ebaSWaiman Long	"  S+    C0-1     .      .  P1:C2-3  C0-2   .      .      .     0 A1:0-2,B1:2-3 A1:P0,B1:P-1"
301a8c52ebaSWaiman Long
302a8c52ebaSWaiman Long	# test  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate
303a8c52ebaSWaiman Long	# ----  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------
304a8c52ebaSWaiman Long	# Failure cases:
305a8c52ebaSWaiman Long
306a8c52ebaSWaiman Long	# A task cannot be added to a partition with no cpu
307a8c52ebaSWaiman Long	"  S+ C2-3:P1:S+  C3:P1  .      .    O2-0:T   .      .      .     1 A1:,A2:3 A1:P1,A2:P1"
308a8c52ebaSWaiman Long)
309a8c52ebaSWaiman Long
310a8c52ebaSWaiman Long#
311a8c52ebaSWaiman Long# Write to the cpu online file
312a8c52ebaSWaiman Long#  $1 - <c>-<v> where <c> = cpu number, <v> value to be written
313a8c52ebaSWaiman Long#
314a8c52ebaSWaiman Longwrite_cpu_online()
315a8c52ebaSWaiman Long{
316a8c52ebaSWaiman Long	CPU=${1%-*}
317a8c52ebaSWaiman Long	VAL=${1#*-}
318a8c52ebaSWaiman Long	CPUFILE=//sys/devices/system/cpu/cpu${CPU}/online
319a8c52ebaSWaiman Long	if [[ $VAL -eq 0 ]]
320a8c52ebaSWaiman Long	then
321a8c52ebaSWaiman Long		OFFLINE_CPUS="$OFFLINE_CPUS $CPU"
322a8c52ebaSWaiman Long	else
323a8c52ebaSWaiman Long		[[ -n "$OFFLINE_CPUS" ]] && {
324a8c52ebaSWaiman Long			OFFLINE_CPUS=$(echo $CPU $CPU $OFFLINE_CPUS | fmt -1 |\
325a8c52ebaSWaiman Long					sort | uniq -u)
326a8c52ebaSWaiman Long		}
327a8c52ebaSWaiman Long	fi
328a8c52ebaSWaiman Long	echo $VAL > $CPUFILE
329a8c52ebaSWaiman Long	pause 0.01
330a8c52ebaSWaiman Long}
331a8c52ebaSWaiman Long
332a8c52ebaSWaiman Long#
333a8c52ebaSWaiman Long# Set controller state
334a8c52ebaSWaiman Long#  $1 - cgroup directory
335a8c52ebaSWaiman Long#  $2 - state
336a8c52ebaSWaiman Long#  $3 - showerr
337a8c52ebaSWaiman Long#
338a8c52ebaSWaiman Long# The presence of ":" in state means transition from one to the next.
339a8c52ebaSWaiman Long#
340a8c52ebaSWaiman Longset_ctrl_state()
341a8c52ebaSWaiman Long{
342a8c52ebaSWaiman Long	TMPMSG=/tmp/.msg_$$
343a8c52ebaSWaiman Long	CGRP=$1
344a8c52ebaSWaiman Long	STATE=$2
345a8c52ebaSWaiman Long	SHOWERR=${3}${VERBOSE}
346a8c52ebaSWaiman Long	CTRL=${CTRL:=$CONTROLLER}
347a8c52ebaSWaiman Long	HASERR=0
348a8c52ebaSWaiman Long	REDIRECT="2> $TMPMSG"
349a8c52ebaSWaiman Long	[[ -z "$STATE" || "$STATE" = '.' ]] && return 0
350a8c52ebaSWaiman Long
351a8c52ebaSWaiman Long	rm -f $TMPMSG
352a8c52ebaSWaiman Long	for CMD in $(echo $STATE | sed -e "s/:/ /g")
353a8c52ebaSWaiman Long	do
354a8c52ebaSWaiman Long		TFILE=$CGRP/cgroup.procs
355a8c52ebaSWaiman Long		SFILE=$CGRP/cgroup.subtree_control
356a8c52ebaSWaiman Long		PFILE=$CGRP/cpuset.cpus.partition
357a8c52ebaSWaiman Long		CFILE=$CGRP/cpuset.cpus
358a8c52ebaSWaiman Long		S=$(expr substr $CMD 1 1)
359a8c52ebaSWaiman Long		if [[ $S = S ]]
360a8c52ebaSWaiman Long		then
361a8c52ebaSWaiman Long			PREFIX=${CMD#?}
362a8c52ebaSWaiman Long			COMM="echo ${PREFIX}${CTRL} > $SFILE"
363a8c52ebaSWaiman Long			eval $COMM $REDIRECT
364a8c52ebaSWaiman Long		elif [[ $S = C ]]
365a8c52ebaSWaiman Long		then
366a8c52ebaSWaiman Long			CPUS=${CMD#?}
367a8c52ebaSWaiman Long			COMM="echo $CPUS > $CFILE"
368a8c52ebaSWaiman Long			eval $COMM $REDIRECT
369a8c52ebaSWaiman Long		elif [[ $S = P ]]
370a8c52ebaSWaiman Long		then
371a8c52ebaSWaiman Long			VAL=${CMD#?}
372a8c52ebaSWaiman Long			case $VAL in
373a8c52ebaSWaiman Long			0)  VAL=member
374a8c52ebaSWaiman Long			    ;;
375a8c52ebaSWaiman Long			1)  VAL=root
376a8c52ebaSWaiman Long			    ;;
377a8c52ebaSWaiman Long			2)  VAL=isolated
378a8c52ebaSWaiman Long			    ;;
379a8c52ebaSWaiman Long			*)
380a8c52ebaSWaiman Long			    echo "Invalid partition state - $VAL"
381a8c52ebaSWaiman Long			    exit 1
382a8c52ebaSWaiman Long			    ;;
383a8c52ebaSWaiman Long			esac
384a8c52ebaSWaiman Long			COMM="echo $VAL > $PFILE"
385a8c52ebaSWaiman Long			eval $COMM $REDIRECT
386a8c52ebaSWaiman Long		elif [[ $S = O ]]
387a8c52ebaSWaiman Long		then
388a8c52ebaSWaiman Long			VAL=${CMD#?}
389a8c52ebaSWaiman Long			write_cpu_online $VAL
390a8c52ebaSWaiman Long		elif [[ $S = T ]]
391a8c52ebaSWaiman Long		then
392a8c52ebaSWaiman Long			COMM="echo 0 > $TFILE"
393a8c52ebaSWaiman Long			eval $COMM $REDIRECT
394a8c52ebaSWaiman Long		fi
395a8c52ebaSWaiman Long		RET=$?
396a8c52ebaSWaiman Long		[[ $RET -ne 0 ]] && {
397a8c52ebaSWaiman Long			[[ -n "$SHOWERR" ]] && {
398a8c52ebaSWaiman Long				echo "$COMM"
399a8c52ebaSWaiman Long				cat $TMPMSG
400a8c52ebaSWaiman Long			}
401a8c52ebaSWaiman Long			HASERR=1
402a8c52ebaSWaiman Long		}
403a8c52ebaSWaiman Long		pause 0.01
404a8c52ebaSWaiman Long		rm -f $TMPMSG
405a8c52ebaSWaiman Long	done
406a8c52ebaSWaiman Long	return $HASERR
407a8c52ebaSWaiman Long}
408a8c52ebaSWaiman Long
409a8c52ebaSWaiman Longset_ctrl_state_noerr()
410a8c52ebaSWaiman Long{
411a8c52ebaSWaiman Long	CGRP=$1
412a8c52ebaSWaiman Long	STATE=$2
413a8c52ebaSWaiman Long	[[ -d $CGRP ]] || mkdir $CGRP
414a8c52ebaSWaiman Long	set_ctrl_state $CGRP $STATE 1
415a8c52ebaSWaiman Long	[[ $? -ne 0 ]] && {
416a8c52ebaSWaiman Long		echo "ERROR: Failed to set $2 to cgroup $1!"
417a8c52ebaSWaiman Long		exit 1
418a8c52ebaSWaiman Long	}
419a8c52ebaSWaiman Long}
420a8c52ebaSWaiman Long
421a8c52ebaSWaiman Longonline_cpus()
422a8c52ebaSWaiman Long{
423a8c52ebaSWaiman Long	[[ -n "OFFLINE_CPUS" ]] && {
424a8c52ebaSWaiman Long		for C in $OFFLINE_CPUS
425a8c52ebaSWaiman Long		do
426a8c52ebaSWaiman Long			write_cpu_online ${C}-1
427a8c52ebaSWaiman Long		done
428a8c52ebaSWaiman Long	}
429a8c52ebaSWaiman Long}
430a8c52ebaSWaiman Long
431a8c52ebaSWaiman Long#
432a8c52ebaSWaiman Long# Return 1 if the list of effective cpus isn't the same as the initial list.
433a8c52ebaSWaiman Long#
434a8c52ebaSWaiman Longreset_cgroup_states()
435a8c52ebaSWaiman Long{
436a8c52ebaSWaiman Long	echo 0 > $CGROUP2/cgroup.procs
437a8c52ebaSWaiman Long	online_cpus
438a8c52ebaSWaiman Long	rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1
439a8c52ebaSWaiman Long	set_ctrl_state . S-
440a8c52ebaSWaiman Long	pause 0.01
441a8c52ebaSWaiman Long}
442a8c52ebaSWaiman Long
443a8c52ebaSWaiman Longdump_states()
444a8c52ebaSWaiman Long{
445a8c52ebaSWaiman Long	for DIR in A1 A1/A2 A1/A2/A3 B1
446a8c52ebaSWaiman Long	do
447a8c52ebaSWaiman Long		ECPUS=$DIR/cpuset.cpus.effective
448a8c52ebaSWaiman Long		PRS=$DIR/cpuset.cpus.partition
449a8c52ebaSWaiman Long		[[ -e $ECPUS ]] && echo "$ECPUS: $(cat $ECPUS)"
450a8c52ebaSWaiman Long		[[ -e $PRS   ]] && echo "$PRS: $(cat $PRS)"
451a8c52ebaSWaiman Long	done
452a8c52ebaSWaiman Long}
453a8c52ebaSWaiman Long
454a8c52ebaSWaiman Long#
455a8c52ebaSWaiman Long# Check effective cpus
456a8c52ebaSWaiman Long# $1 - check string, format: <cgroup>:<cpu-list>[,<cgroup>:<cpu-list>]*
457a8c52ebaSWaiman Long#
458a8c52ebaSWaiman Longcheck_effective_cpus()
459a8c52ebaSWaiman Long{
460a8c52ebaSWaiman Long	CHK_STR=$1
461a8c52ebaSWaiman Long	for CHK in $(echo $CHK_STR | sed -e "s/,/ /g")
462a8c52ebaSWaiman Long	do
463a8c52ebaSWaiman Long		set -- $(echo $CHK | sed -e "s/:/ /g")
464a8c52ebaSWaiman Long		CGRP=$1
465a8c52ebaSWaiman Long		CPUS=$2
466a8c52ebaSWaiman Long		[[ $CGRP = A2 ]] && CGRP=A1/A2
467a8c52ebaSWaiman Long		[[ $CGRP = A3 ]] && CGRP=A1/A2/A3
468a8c52ebaSWaiman Long		FILE=$CGRP/cpuset.cpus.effective
469a8c52ebaSWaiman Long		[[ -e $FILE ]] || return 1
470a8c52ebaSWaiman Long		[[ $CPUS = $(cat $FILE) ]] || return 1
471a8c52ebaSWaiman Long	done
472a8c52ebaSWaiman Long}
473a8c52ebaSWaiman Long
474a8c52ebaSWaiman Long#
475a8c52ebaSWaiman Long# Check cgroup states
476a8c52ebaSWaiman Long#  $1 - check string, format: <cgroup>:<state>[,<cgroup>:<state>]*
477a8c52ebaSWaiman Long#
478a8c52ebaSWaiman Longcheck_cgroup_states()
479a8c52ebaSWaiman Long{
480a8c52ebaSWaiman Long	CHK_STR=$1
481a8c52ebaSWaiman Long	for CHK in $(echo $CHK_STR | sed -e "s/,/ /g")
482a8c52ebaSWaiman Long	do
483a8c52ebaSWaiman Long		set -- $(echo $CHK | sed -e "s/:/ /g")
484a8c52ebaSWaiman Long		CGRP=$1
485a8c52ebaSWaiman Long		STATE=$2
486a8c52ebaSWaiman Long		FILE=
487a8c52ebaSWaiman Long		EVAL=$(expr substr $STATE 2 2)
488a8c52ebaSWaiman Long		[[ $CGRP = A2 ]] && CGRP=A1/A2
489a8c52ebaSWaiman Long		[[ $CGRP = A3 ]] && CGRP=A1/A2/A3
490a8c52ebaSWaiman Long
491a8c52ebaSWaiman Long		case $STATE in
492a8c52ebaSWaiman Long			P*) FILE=$CGRP/cpuset.cpus.partition
493a8c52ebaSWaiman Long			    ;;
494a8c52ebaSWaiman Long			*)  echo "Unknown state: $STATE!"
495a8c52ebaSWaiman Long			    exit 1
496a8c52ebaSWaiman Long			    ;;
497a8c52ebaSWaiman Long		esac
498a8c52ebaSWaiman Long		VAL=$(cat $FILE)
499a8c52ebaSWaiman Long
500a8c52ebaSWaiman Long		case "$VAL" in
501a8c52ebaSWaiman Long			member) VAL=0
502a8c52ebaSWaiman Long				;;
503a8c52ebaSWaiman Long			root)	VAL=1
504a8c52ebaSWaiman Long				;;
505a8c52ebaSWaiman Long			isolated)
506a8c52ebaSWaiman Long				VAL=2
507a8c52ebaSWaiman Long				;;
508a8c52ebaSWaiman Long			"root invalid"*)
509a8c52ebaSWaiman Long				VAL=-1
510a8c52ebaSWaiman Long				;;
511a8c52ebaSWaiman Long			"isolated invalid"*)
512a8c52ebaSWaiman Long				VAL=-2
513a8c52ebaSWaiman Long				;;
514a8c52ebaSWaiman Long		esac
515a8c52ebaSWaiman Long		[[ $EVAL != $VAL ]] && return 1
516a8c52ebaSWaiman Long	done
517a8c52ebaSWaiman Long	return 0
518a8c52ebaSWaiman Long}
519a8c52ebaSWaiman Long
520a8c52ebaSWaiman Long#
521a8c52ebaSWaiman Long# Run cpuset state transition test
522a8c52ebaSWaiman Long#  $1 - test matrix name
523a8c52ebaSWaiman Long#
524a8c52ebaSWaiman Long# This test is somewhat fragile as delays (sleep x) are added in various
525a8c52ebaSWaiman Long# places to make sure state changes are fully propagated before the next
526a8c52ebaSWaiman Long# action. These delays may need to be adjusted if running in a slower machine.
527a8c52ebaSWaiman Long#
528a8c52ebaSWaiman Longrun_state_test()
529a8c52ebaSWaiman Long{
530a8c52ebaSWaiman Long	TEST=$1
531a8c52ebaSWaiman Long	CONTROLLER=cpuset
532a8c52ebaSWaiman Long	CPULIST=0-6
533a8c52ebaSWaiman Long	I=0
534a8c52ebaSWaiman Long	eval CNT="\${#$TEST[@]}"
535a8c52ebaSWaiman Long
536a8c52ebaSWaiman Long	reset_cgroup_states
537a8c52ebaSWaiman Long	echo $CPULIST > cpuset.cpus
538a8c52ebaSWaiman Long	echo root > cpuset.cpus.partition
539a8c52ebaSWaiman Long	console_msg "Running state transition test ..."
540a8c52ebaSWaiman Long
541a8c52ebaSWaiman Long	while [[ $I -lt $CNT ]]
542a8c52ebaSWaiman Long	do
543a8c52ebaSWaiman Long		echo "Running test $I ..." > /dev/console
544a8c52ebaSWaiman Long		eval set -- "\${$TEST[$I]}"
545a8c52ebaSWaiman Long		ROOT=$1
546a8c52ebaSWaiman Long		OLD_A1=$2
547a8c52ebaSWaiman Long		OLD_A2=$3
548a8c52ebaSWaiman Long		OLD_A3=$4
549a8c52ebaSWaiman Long		OLD_B1=$5
550a8c52ebaSWaiman Long		NEW_A1=$6
551a8c52ebaSWaiman Long		NEW_A2=$7
552a8c52ebaSWaiman Long		NEW_A3=$8
553a8c52ebaSWaiman Long		NEW_B1=$9
554a8c52ebaSWaiman Long		RESULT=${10}
555a8c52ebaSWaiman Long		ECPUS=${11}
556a8c52ebaSWaiman Long		STATES=${12}
557a8c52ebaSWaiman Long
558a8c52ebaSWaiman Long		set_ctrl_state_noerr .        $ROOT
559a8c52ebaSWaiman Long		set_ctrl_state_noerr A1       $OLD_A1
560a8c52ebaSWaiman Long		set_ctrl_state_noerr A1/A2    $OLD_A2
561a8c52ebaSWaiman Long		set_ctrl_state_noerr A1/A2/A3 $OLD_A3
562a8c52ebaSWaiman Long		set_ctrl_state_noerr B1       $OLD_B1
563a8c52ebaSWaiman Long		RETVAL=0
564a8c52ebaSWaiman Long		set_ctrl_state A1       $NEW_A1; ((RETVAL += $?))
565a8c52ebaSWaiman Long		set_ctrl_state A1/A2    $NEW_A2; ((RETVAL += $?))
566a8c52ebaSWaiman Long		set_ctrl_state A1/A2/A3 $NEW_A3; ((RETVAL += $?))
567a8c52ebaSWaiman Long		set_ctrl_state B1       $NEW_B1; ((RETVAL += $?))
568a8c52ebaSWaiman Long
569a8c52ebaSWaiman Long		[[ $RETVAL -ne $RESULT ]] && {
570a8c52ebaSWaiman Long			echo "Test $TEST[$I] failed result check!"
571a8c52ebaSWaiman Long			eval echo \"\${$TEST[$I]}\"
572a8c52ebaSWaiman Long			dump_states
573a8c52ebaSWaiman Long			online_cpus
574a8c52ebaSWaiman Long			exit 1
575a8c52ebaSWaiman Long		}
576a8c52ebaSWaiman Long
577a8c52ebaSWaiman Long		[[ -n "$ECPUS" && "$ECPUS" != . ]] && {
578a8c52ebaSWaiman Long			check_effective_cpus $ECPUS
579a8c52ebaSWaiman Long			[[ $? -ne 0 ]] && {
580a8c52ebaSWaiman Long				echo "Test $TEST[$I] failed effective CPU check!"
581a8c52ebaSWaiman Long				eval echo \"\${$TEST[$I]}\"
582a8c52ebaSWaiman Long				echo
583a8c52ebaSWaiman Long				dump_states
584a8c52ebaSWaiman Long				online_cpus
585a8c52ebaSWaiman Long				exit 1
586a8c52ebaSWaiman Long			}
587a8c52ebaSWaiman Long		}
588a8c52ebaSWaiman Long
589a8c52ebaSWaiman Long		[[ -n "$STATES" ]] && {
590a8c52ebaSWaiman Long			check_cgroup_states $STATES
591a8c52ebaSWaiman Long			[[ $? -ne 0 ]] && {
592a8c52ebaSWaiman Long				echo "FAILED: Test $TEST[$I] failed states check!"
593a8c52ebaSWaiman Long				eval echo \"\${$TEST[$I]}\"
594a8c52ebaSWaiman Long				echo
595a8c52ebaSWaiman Long				dump_states
596a8c52ebaSWaiman Long				online_cpus
597a8c52ebaSWaiman Long				exit 1
598a8c52ebaSWaiman Long			}
599a8c52ebaSWaiman Long		}
600a8c52ebaSWaiman Long
601a8c52ebaSWaiman Long		reset_cgroup_states
602a8c52ebaSWaiman Long		#
603a8c52ebaSWaiman Long		# Check to see if effective cpu list changes
604a8c52ebaSWaiman Long		#
605a8c52ebaSWaiman Long		pause 0.05
606a8c52ebaSWaiman Long		NEWLIST=$(cat cpuset.cpus.effective)
607a8c52ebaSWaiman Long		[[ $NEWLIST != $CPULIST ]] && {
608a8c52ebaSWaiman Long			echo "Effective cpus changed to $NEWLIST after test $I!"
609a8c52ebaSWaiman Long			exit 1
610a8c52ebaSWaiman Long		}
611a8c52ebaSWaiman Long		[[ -n "$VERBOSE" ]] && echo "Test $I done."
612a8c52ebaSWaiman Long		((I++))
613a8c52ebaSWaiman Long	done
614a8c52ebaSWaiman Long	echo "All $I tests of $TEST PASSED."
615a8c52ebaSWaiman Long
616a8c52ebaSWaiman Long	echo member > cpuset.cpus.partition
617a8c52ebaSWaiman Long}
618a8c52ebaSWaiman Long
619a8c52ebaSWaiman Long#
620a8c52ebaSWaiman Long# Wait for inotify event for the given file and read it
621a8c52ebaSWaiman Long# $1: cgroup file to wait for
622a8c52ebaSWaiman Long# $2: file to store the read result
623a8c52ebaSWaiman Long#
624a8c52ebaSWaiman Longwait_inotify()
625a8c52ebaSWaiman Long{
626a8c52ebaSWaiman Long	CGROUP_FILE=$1
627a8c52ebaSWaiman Long	OUTPUT_FILE=$2
628a8c52ebaSWaiman Long
629a8c52ebaSWaiman Long	$WAIT_INOTIFY $CGROUP_FILE
630a8c52ebaSWaiman Long	cat $CGROUP_FILE > $OUTPUT_FILE
631a8c52ebaSWaiman Long}
632a8c52ebaSWaiman Long
633a8c52ebaSWaiman Long#
634a8c52ebaSWaiman Long# Test if inotify events are properly generated when going into and out of
635a8c52ebaSWaiman Long# invalid partition state.
636a8c52ebaSWaiman Long#
637a8c52ebaSWaiman Longtest_inotify()
638a8c52ebaSWaiman Long{
639a8c52ebaSWaiman Long	ERR=0
640a8c52ebaSWaiman Long	PRS=/tmp/.prs_$$
641a8c52ebaSWaiman Long	[[ -f $WAIT_INOTIFY ]] || {
642a8c52ebaSWaiman Long		echo "wait_inotify not found, inotify test SKIPPED."
643a8c52ebaSWaiman Long		return
644a8c52ebaSWaiman Long	}
645a8c52ebaSWaiman Long
646a8c52ebaSWaiman Long	pause 0.01
647a8c52ebaSWaiman Long	echo 1 > cpuset.cpus
648a8c52ebaSWaiman Long	echo 0 > cgroup.procs
649a8c52ebaSWaiman Long	echo root > cpuset.cpus.partition
650a8c52ebaSWaiman Long	pause 0.01
651a8c52ebaSWaiman Long	rm -f $PRS
652a8c52ebaSWaiman Long	wait_inotify $PWD/cpuset.cpus.partition $PRS &
653a8c52ebaSWaiman Long	pause 0.01
654a8c52ebaSWaiman Long	set_ctrl_state . "O1-0"
655a8c52ebaSWaiman Long	pause 0.01
656a8c52ebaSWaiman Long	check_cgroup_states ".:P-1"
657a8c52ebaSWaiman Long	if [[ $? -ne 0 ]]
658a8c52ebaSWaiman Long	then
659a8c52ebaSWaiman Long		echo "FAILED: Inotify test - partition not invalid"
660a8c52ebaSWaiman Long		ERR=1
661a8c52ebaSWaiman Long	elif [[ ! -f $PRS ]]
662a8c52ebaSWaiman Long	then
663a8c52ebaSWaiman Long		echo "FAILED: Inotify test - event not generated"
664a8c52ebaSWaiman Long		ERR=1
665a8c52ebaSWaiman Long		kill %1
666a8c52ebaSWaiman Long	elif [[ $(cat $PRS) != "root invalid"* ]]
667a8c52ebaSWaiman Long	then
668a8c52ebaSWaiman Long		echo "FAILED: Inotify test - incorrect state"
669a8c52ebaSWaiman Long		cat $PRS
670a8c52ebaSWaiman Long		ERR=1
671a8c52ebaSWaiman Long	fi
672a8c52ebaSWaiman Long	online_cpus
673a8c52ebaSWaiman Long	echo member > cpuset.cpus.partition
674a8c52ebaSWaiman Long	echo 0 > ../cgroup.procs
675a8c52ebaSWaiman Long	if [[ $ERR -ne 0 ]]
676a8c52ebaSWaiman Long	then
677a8c52ebaSWaiman Long		exit 1
678a8c52ebaSWaiman Long	else
679a8c52ebaSWaiman Long		echo "Inotify test PASSED"
680a8c52ebaSWaiman Long	fi
681a8c52ebaSWaiman Long}
682a8c52ebaSWaiman Long
683*1e85591dSKamalesh Babulaltrap cleanup 0 2 3 6
684a8c52ebaSWaiman Longrun_state_test TEST_MATRIX
685a8c52ebaSWaiman Longtest_isolated
686a8c52ebaSWaiman Longtest_inotify
687a8c52ebaSWaiman Longecho "All tests PASSED."
688a8c52ebaSWaiman Longcd ..
689a8c52ebaSWaiman Longrmdir test
690