Commit | Line | Data |
---|---|---|
a8c52eba WL |
1 | #!/bin/bash |
2 | # SPDX-License-Identifier: GPL-2.0 | |
3 | # | |
4 | # Test for cpuset v2 partition root state (PRS) | |
5 | # | |
105f3fe9 | 6 | # The sched verbose flag can be optionally set so that the console log |
a8c52eba WL |
7 | # can be examined for the correct setting of scheduling domain. |
8 | # | |
9 | ||
10 | skip_test() { | |
11 | echo "$1" | |
12 | echo "Test SKIPPED" | |
12101424 | 13 | exit 4 # ksft_skip |
a8c52eba WL |
14 | } |
15 | ||
16 | [[ $(id -u) -eq 0 ]] || skip_test "Test must be run as root!" | |
17 | ||
a8c52eba WL |
18 | |
19 | # Get wait_inotify location | |
20 | WAIT_INOTIFY=$(cd $(dirname $0); pwd)/wait_inotify | |
21 | ||
22 | # Find cgroup v2 mount point | |
23 | CGROUP2=$(mount -t cgroup2 | head -1 | awk -e '{print $3}') | |
24 | [[ -n "$CGROUP2" ]] || skip_test "Cgroup v2 mount point not found!" | |
105f3fe9 WL |
25 | SUBPARTS_CPUS=$CGROUP2/.__DEBUG__.cpuset.cpus.subpartitions |
26 | CPULIST=$(cat $CGROUP2/cpuset.cpus.effective) | |
a8c52eba | 27 | |
105f3fe9 WL |
28 | NR_CPUS=$(lscpu | grep "^CPU(s):" | sed -e "s/.*:[[:space:]]*//") |
29 | [[ $NR_CPUS -lt 8 ]] && skip_test "Test needs at least 8 cpus available!" | |
a8c52eba WL |
30 | |
31 | # Set verbose flag and delay factor | |
32 | PROG=$1 | |
105f3fe9 | 33 | VERBOSE=0 |
a8c52eba | 34 | DELAY_FACTOR=1 |
1bf33285 | 35 | SCHED_DEBUG= |
a8c52eba WL |
36 | while [[ "$1" = -* ]] |
37 | do | |
38 | case "$1" in | |
105f3fe9 | 39 | -v) ((VERBOSE++)) |
1bf33285 WL |
40 | # Enable sched/verbose can slow thing down |
41 | [[ $DELAY_FACTOR -eq 1 ]] && | |
42 | DELAY_FACTOR=2 | |
a8c52eba WL |
43 | ;; |
44 | -d) DELAY_FACTOR=$2 | |
45 | shift | |
a8c52eba WL |
46 | ;; |
47 | *) echo "Usage: $PROG [-v] [-d <delay-factor>" | |
48 | exit | |
49 | ;; | |
50 | esac | |
51 | shift | |
52 | done | |
53 | ||
1bf33285 | 54 | # Set sched verbose flag if available when "-v" option is specified |
105f3fe9 | 55 | if [[ $VERBOSE -gt 0 && -d /sys/kernel/debug/sched ]] |
1bf33285 WL |
56 | then |
57 | # Used to restore the original setting during cleanup | |
58 | SCHED_DEBUG=$(cat /sys/kernel/debug/sched/verbose) | |
59 | echo Y > /sys/kernel/debug/sched/verbose | |
60 | fi | |
61 | ||
a8c52eba WL |
62 | cd $CGROUP2 |
63 | echo +cpuset > cgroup.subtree_control | |
105f3fe9 WL |
64 | |
65 | # | |
66 | # If cpuset has been set up and used in child cgroups, we may not be able to | |
67 | # create partition under root cgroup because of the CPU exclusivity rule. | |
68 | # So we are going to skip the test if this is the case. | |
69 | # | |
a8c52eba | 70 | [[ -d test ]] || mkdir test |
105f3fe9 WL |
71 | echo 0-6 > test/cpuset.cpus |
72 | echo root > test/cpuset.cpus.partition | |
73 | cat test/cpuset.cpus.partition | grep -q invalid | |
74 | RESULT=$? | |
75 | echo member > test/cpuset.cpus.partition | |
76 | echo "" > test/cpuset.cpus | |
77 | [[ $RESULT -eq 0 ]] && skip_test "Child cgroups are using cpuset!" | |
a8c52eba | 78 | |
1e85591d KB |
79 | cleanup() |
80 | { | |
81 | online_cpus | |
105f3fe9 | 82 | cd $CGROUP2 |
1e85591d | 83 | rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1 |
1e85591d | 84 | rmdir test > /dev/null 2>&1 |
1bf33285 WL |
85 | [[ -n "$SCHED_DEBUG" ]] && |
86 | echo "$SCHED_DEBUG" > /sys/kernel/debug/sched/verbose | |
1e85591d KB |
87 | } |
88 | ||
a8c52eba WL |
89 | # Pause in ms |
90 | pause() | |
91 | { | |
92 | DELAY=$1 | |
93 | LOOP=0 | |
94 | while [[ $LOOP -lt $DELAY_FACTOR ]] | |
95 | do | |
96 | sleep $DELAY | |
97 | ((LOOP++)) | |
98 | done | |
99 | return 0 | |
100 | } | |
101 | ||
102 | console_msg() | |
103 | { | |
104 | MSG=$1 | |
105 | echo "$MSG" | |
106 | echo "" > /dev/console | |
107 | echo "$MSG" > /dev/console | |
108 | pause 0.01 | |
109 | } | |
110 | ||
111 | test_partition() | |
112 | { | |
113 | EXPECTED_VAL=$1 | |
114 | echo $EXPECTED_VAL > cpuset.cpus.partition | |
115 | [[ $? -eq 0 ]] || exit 1 | |
116 | ACTUAL_VAL=$(cat cpuset.cpus.partition) | |
117 | [[ $ACTUAL_VAL != $EXPECTED_VAL ]] && { | |
105f3fe9 | 118 | echo "cpuset.cpus.partition: expect $EXPECTED_VAL, found $ACTUAL_VAL" |
a8c52eba WL |
119 | echo "Test FAILED" |
120 | exit 1 | |
121 | } | |
122 | } | |
123 | ||
124 | test_effective_cpus() | |
125 | { | |
126 | EXPECTED_VAL=$1 | |
127 | ACTUAL_VAL=$(cat cpuset.cpus.effective) | |
128 | [[ "$ACTUAL_VAL" != "$EXPECTED_VAL" ]] && { | |
105f3fe9 | 129 | echo "cpuset.cpus.effective: expect '$EXPECTED_VAL', found '$ACTUAL_VAL'" |
a8c52eba WL |
130 | echo "Test FAILED" |
131 | exit 1 | |
132 | } | |
133 | } | |
134 | ||
135 | # Adding current process to cgroup.procs as a test | |
136 | test_add_proc() | |
137 | { | |
138 | OUTSTR="$1" | |
139 | ERRMSG=$((echo $$ > cgroup.procs) |& cat) | |
140 | echo $ERRMSG | grep -q "$OUTSTR" | |
141 | [[ $? -ne 0 ]] && { | |
142 | echo "cgroup.procs: expect '$OUTSTR', got '$ERRMSG'" | |
143 | echo "Test FAILED" | |
144 | exit 1 | |
145 | } | |
146 | echo $$ > $CGROUP2/cgroup.procs # Move out the task | |
147 | } | |
148 | ||
a8c52eba WL |
149 | # |
150 | # Cpuset controller state transition test matrix. | |
151 | # | |
152 | # Cgroup test hierarchy | |
153 | # | |
105f3fe9 WL |
154 | # root -- A1 -- A2 -- A3 |
155 | # +- B1 | |
a8c52eba | 156 | # |
105f3fe9 | 157 | # P<v> = set cpus.partition (0:member, 1:root, 2:isolated) |
46c521ba WL |
158 | # C<l> = add cpu-list to cpuset.cpus |
159 | # X<l> = add cpu-list to cpuset.cpus.exclusive | |
a8c52eba WL |
160 | # S<p> = use prefix in subtree_control |
161 | # T = put a task into cgroup | |
105f3fe9 | 162 | # O<c>=<v> = Write <v> to CPU online file of <c> |
a8c52eba WL |
163 | # |
164 | SETUP_A123_PARTITIONS="C1-3:P1:S+ C2-3:P1:S+ C3:P1" | |
165 | TEST_MATRIX=( | |
105f3fe9 WL |
166 | # old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS |
167 | # ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ -------- | |
168 | " C0-1 . . C2-3 S+ C4-5 . . 0 A2:0-1" | |
169 | " C0-1 . . C2-3 P1 . . . 0 " | |
170 | " C0-1 . . C2-3 P1:S+ C0-1:P1 . . 0 " | |
171 | " C0-1 . . C2-3 P1:S+ C1:P1 . . 0 " | |
172 | " C0-1:S+ . . C2-3 . . . P1 0 " | |
173 | " C0-1:P1 . . C2-3 S+ C1 . . 0 " | |
174 | " C0-1:P1 . . C2-3 S+ C1:P1 . . 0 " | |
175 | " C0-1:P1 . . C2-3 S+ C1:P1 . P1 0 " | |
176 | " C0-1:P1 . . C2-3 C4-5 . . . 0 A1:4-5" | |
177 | " C0-1:P1 . . C2-3 S+:C4-5 . . . 0 A1:4-5" | |
178 | " C0-1 . . C2-3:P1 . . . C2 0 " | |
179 | " C0-1 . . C2-3:P1 . . . C4-5 0 B1:4-5" | |
180 | "C0-3:P1:S+ C2-3:P1 . . . . . . 0 A1:0-1,A2:2-3" | |
181 | "C0-3:P1:S+ C2-3:P1 . . C1-3 . . . 0 A1:1,A2:2-3" | |
182 | "C2-3:P1:S+ C3:P1 . . C3 . . . 0 A1:,A2:3 A1:P1,A2:P1" | |
183 | "C2-3:P1:S+ C3:P1 . . C3 P0 . . 0 A1:3,A2:3 A1:P1,A2:P0" | |
184 | "C2-3:P1:S+ C2:P1 . . C2-4 . . . 0 A1:3-4,A2:2" | |
185 | "C2-3:P1:S+ C3:P1 . . C3 . . C0-2 0 A1:,B1:0-2 A1:P1,A2:P1" | |
186 | "$SETUP_A123_PARTITIONS . C2-3 . . . 0 A1:,A2:2,A3:3 A1:P1,A2:P1,A3:P1" | |
a8c52eba WL |
187 | |
188 | # CPU offlining cases: | |
105f3fe9 WL |
189 | " C0-1 . . C2-3 S+ C4-5 . O2=0 0 A1:0-1,B1:3" |
190 | "C0-3:P1:S+ C2-3:P1 . . O2=0 . . . 0 A1:0-1,A2:3" | |
191 | "C0-3:P1:S+ C2-3:P1 . . O2=0 O2=1 . . 0 A1:0-1,A2:2-3" | |
192 | "C0-3:P1:S+ C2-3:P1 . . O1=0 . . . 0 A1:0,A2:2-3" | |
193 | "C0-3:P1:S+ C2-3:P1 . . O1=0 O1=1 . . 0 A1:0-1,A2:2-3" | |
194 | "C2-3:P1:S+ C3:P1 . . O3=0 O3=1 . . 0 A1:2,A2:3 A1:P1,A2:P1" | |
195 | "C2-3:P1:S+ C3:P2 . . O3=0 O3=1 . . 0 A1:2,A2:3 A1:P1,A2:P2" | |
196 | "C2-3:P1:S+ C3:P1 . . O2=0 O2=1 . . 0 A1:2,A2:3 A1:P1,A2:P1" | |
197 | "C2-3:P1:S+ C3:P2 . . O2=0 O2=1 . . 0 A1:2,A2:3 A1:P1,A2:P2" | |
198 | "C2-3:P1:S+ C3:P1 . . O2=0 . . . 0 A1:,A2:3 A1:P1,A2:P1" | |
199 | "C2-3:P1:S+ C3:P1 . . O3=0 . . . 0 A1:2,A2: A1:P1,A2:P1" | |
200 | "C2-3:P1:S+ C3:P1 . . T:O2=0 . . . 0 A1:3,A2:3 A1:P1,A2:P-1" | |
201 | "C2-3:P1:S+ C3:P1 . . . T:O3=0 . . 0 A1:2,A2:2 A1:P1,A2:P-1" | |
202 | "$SETUP_A123_PARTITIONS . O1=0 . . . 0 A1:,A2:2,A3:3 A1:P1,A2:P1,A3:P1" | |
203 | "$SETUP_A123_PARTITIONS . O2=0 . . . 0 A1:1,A2:,A3:3 A1:P1,A2:P1,A3:P1" | |
204 | "$SETUP_A123_PARTITIONS . O3=0 . . . 0 A1:1,A2:2,A3: A1:P1,A2:P1,A3:P1" | |
205 | "$SETUP_A123_PARTITIONS . T:O1=0 . . . 0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1" | |
206 | "$SETUP_A123_PARTITIONS . . T:O2=0 . . 0 A1:1,A2:3,A3:3 A1:P1,A2:P1,A3:P-1" | |
207 | "$SETUP_A123_PARTITIONS . . . T:O3=0 . 0 A1:1,A2:2,A3:2 A1:P1,A2:P1,A3:P-1" | |
208 | "$SETUP_A123_PARTITIONS . T:O1=0 O1=1 . . 0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1" | |
209 | "$SETUP_A123_PARTITIONS . . T:O2=0 O2=1 . 0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1" | |
210 | "$SETUP_A123_PARTITIONS . . . T:O3=0 O3=1 0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1" | |
211 | "$SETUP_A123_PARTITIONS . T:O1=0 O2=0 O1=1 . 0 A1:1,A2:,A3:3 A1:P1,A2:P1,A3:P1" | |
212 | "$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" | |
213 | ||
214 | # old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS | |
215 | # ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ -------- | |
216 | # | |
217 | # Remote partition and cpuset.cpus.exclusive tests | |
218 | # | |
219 | " C0-3:S+ C1-3:S+ C2-3 . X2-3 . . . 0 A1:0-3,A2:1-3,A3:2-3,XA1:2-3" | |
220 | " 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" | |
221 | " 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" | |
222 | " 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" | |
223 | " C0-3:S+ C1-3:S+ C2-3 . X2-3 X2-3 X2-3:P2:C3 . 0 A1:0-2,A2:1-2,A3:3 A1:P0,A3:P2 3" | |
224 | " 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" | |
225 | " C0-3:S+ C1-3:S+ C2-3 C4-5 . . . P2 0 B1:4-5 B1:P2 4-5" | |
226 | " 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" | |
227 | " 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" | |
228 | " 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" | |
229 | " 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" | |
230 | ||
231 | # Nested remote/local partition tests | |
232 | " 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 \ | |
233 | A1:P0,A2:P1,A3:P2,B1:P1 2-3" | |
234 | " 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 \ | |
72c6303a | 235 | A1:P0,A2:P1,A3:P2,B1:P1 2-4,2-3" |
105f3fe9 | 236 | " 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 \ |
72c6303a | 237 | A1:P0,A2:P1,A3:P2,B1:P1 2-4,3" |
105f3fe9 | 238 | " C0-4:S+ C1-4:S+ C2-4 . X2-4 X2-4:P2 X4:P1 . 0 A1:0-1,A2:2-3,A3:4 \ |
72c6303a | 239 | A1:P0,A2:P2,A3:P1 2-4,2-3" |
105f3fe9 WL |
240 | " C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \ |
241 | . . X5 . . 0 A1:0-4,A2:1-4,A3:2-4 \ | |
14060dfc | 242 | A1:P0,A2:P-2,A3:P-1" |
105f3fe9 WL |
243 | " C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \ |
244 | . . . X1 . 0 A1:0-1,A2:2-4,A3:2-4 \ | |
245 | A1:P0,A2:P2,A3:P-1 2-4" | |
246 | ||
247 | # Remote partition offline tests | |
248 | " 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" | |
249 | " 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" | |
250 | " 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" | |
72c6303a | 251 | " 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," |
105f3fe9 WL |
252 | |
253 | # An invalidated remote partition cannot self-recover from hotplug | |
254 | " 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" | |
255 | ||
256 | # cpus.exclusive.effective clearing test | |
46c521ba | 257 | " C0-3:S+ C1-3:S+ C2 . X2-3:X . . . 0 A1:0-3,A2:1-3,A3:2,XA1:" |
105f3fe9 | 258 | |
46c521ba WL |
259 | # Invalid to valid remote partition transition test |
260 | " C0-3:S+ C1-3 . . . X3:P2 . . 0 A1:0-3,A2:1-3,XA2: A2:P-2" | |
105f3fe9 | 261 | " C0-3:S+ C1-3:X3:P2 |
46c521ba | 262 | . . X2-3 P2 . . 0 A1:0-2,A2:3,XA2:3 A2:P2 3" |
105f3fe9 WL |
263 | |
264 | # Invalid to valid local partition direct transition tests | |
46c521ba WL |
265 | " C1-3:S+:P2 C2-3:X1:P2 . . . . . . 0 A1:1-3,XA1:1-3,A2:2-3:XA2: A1:P2,A2:P-2 1-3" |
266 | " C1-3:S+:P2 C2-3:X1:P2 . . . X3:P2 . . 0 A1:1-2,XA1:1-3,A2:3:XA2:3 A1:P2,A2:P2 1-3" | |
267 | " C0-3:P2 . . C4-6 C0-4 . . . 0 A1:0-4,B1:4-6 A1:P-2,B1:P0" | |
268 | " C0-3:P2 . . C4-6 C0-4:C0-3 . . . 0 A1:0-3,B1:4-6 A1:P2,B1:P0 0-3" | |
269 | " C0-3:P2 . . C3-5:C4-5 . . . . 0 A1:0-3,B1:4-5 A1:P2,B1:P0 0-3" | |
105f3fe9 WL |
270 | |
271 | # Local partition invalidation tests | |
272 | " C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \ | |
273 | . . . . . 0 A1:1,A2:2,A3:3 A1:P2,A2:P2,A3:P2 1-3" | |
274 | " C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \ | |
275 | . . X4 . . 0 A1:1-3,A2:1-3,A3:2-3,XA2:,XA3: A1:P2,A2:P-2,A3:P-2 1-3" | |
276 | " C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \ | |
277 | . . C4 . . 0 A1:1-3,A2:1-3,A3:2-3,XA2:,XA3: A1:P2,A2:P-2,A3:P-2 1-3" | |
46c521ba WL |
278 | # Local partition CPU change tests |
279 | " C0-5:S+:P2 C4-5:S+:P1 . . . C3-5 . . 0 A1:0-2,A2:3-5 A1:P2,A2:P1 0-2" | |
280 | " C0-5:S+:P2 C4-5:S+:P1 . . C1-5 . . . 0 A1:1-3,A2:4-5 A1:P2,A2:P1 1-3" | |
105f3fe9 WL |
281 | |
282 | # cpus_allowed/exclusive_cpus update tests | |
283 | " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \ | |
284 | . C4 . P2 . 0 A1:4,A2:4,XA2:,XA3:,A3:4 \ | |
14060dfc | 285 | A1:P0,A3:P-2" |
105f3fe9 WL |
286 | " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \ |
287 | . X1 . P2 . 0 A1:0-3,A2:1-3,XA1:1,XA2:,XA3:,A3:2-3 \ | |
14060dfc | 288 | A1:P0,A3:P-2" |
105f3fe9 WL |
289 | " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \ |
290 | . . C3 P2 . 0 A1:0-2,A2:0-2,XA2:3,XA3:3,A3:3 \ | |
291 | A1:P0,A3:P2 3" | |
292 | " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \ | |
293 | . . X3 P2 . 0 A1:0-2,A2:1-2,XA2:3,XA3:3,A3:3 \ | |
294 | A1:P0,A3:P2 3" | |
295 | " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \ | |
296 | . . X3 . . 0 A1:0-3,A2:1-3,XA2:3,XA3:3,A3:2-3 \ | |
14060dfc | 297 | A1:P0,A3:P-2" |
105f3fe9 WL |
298 | " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \ |
299 | . . C3 . . 0 A1:0-3,A2:3,XA2:3,XA3:3,A3:3 \ | |
14060dfc | 300 | A1:P0,A3:P-2" |
105f3fe9 WL |
301 | " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \ |
302 | . C4 . . . 0 A1:4,A2:4,A3:4,XA1:,XA2:,XA3 \ | |
14060dfc | 303 | A1:P0,A3:P-2" |
105f3fe9 WL |
304 | |
305 | # old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS | |
306 | # ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ -------- | |
a8c52eba WL |
307 | # |
308 | # Incorrect change to cpuset.cpus invalidates partition root | |
309 | # | |
310 | # Adding CPUs to partition root that are not in parent's | |
311 | # cpuset.cpus is allowed, but those extra CPUs are ignored. | |
105f3fe9 | 312 | "C2-3:P1:S+ C3:P1 . . . C2-4 . . 0 A1:,A2:2-3 A1:P1,A2:P1" |
a8c52eba WL |
313 | |
314 | # Taking away all CPUs from parent or itself if there are tasks | |
315 | # will make the partition invalid. | |
105f3fe9 WL |
316 | "C2-3:P1:S+ C3:P1 . . T C2-3 . . 0 A1:2-3,A2:2-3 A1:P1,A2:P-1" |
317 | " C3:P1:S+ C3 . . T P1 . . 0 A1:3,A2:3 A1:P1,A2:P-1" | |
318 | "$SETUP_A123_PARTITIONS . T:C2-3 . . . 0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1" | |
319 | "$SETUP_A123_PARTITIONS . T:C2-3:C1-3 . . . 0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1" | |
a8c52eba WL |
320 | |
321 | # Changing a partition root to member makes child partitions invalid | |
105f3fe9 WL |
322 | "C2-3:P1:S+ C3:P1 . . P0 . . . 0 A1:2-3,A2:3 A1:P0,A2:P-1" |
323 | "$SETUP_A123_PARTITIONS . C2-3 P0 . . 0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P0,A3:P-1" | |
a8c52eba WL |
324 | |
325 | # cpuset.cpus can contains cpus not in parent's cpuset.cpus as long | |
326 | # as they overlap. | |
105f3fe9 | 327 | "C2-3:P1:S+ . . . . C3-4:P1 . . 0 A1:2,A2:3 A1:P1,A2:P1" |
a8c52eba WL |
328 | |
329 | # Deletion of CPUs distributed to child cgroup is allowed. | |
105f3fe9 | 330 | "C0-1:P1:S+ C1 . C2-3 C4-5 . . . 0 A1:4-5,A2:4-5" |
a8c52eba WL |
331 | |
332 | # To become a valid partition root, cpuset.cpus must overlap parent's | |
333 | # cpuset.cpus. | |
105f3fe9 | 334 | " C0-1:P1 . . C2-3 S+ C4-5:P1 . . 0 A1:0-1,A2:0-1 A1:P1,A2:P-1" |
a8c52eba WL |
335 | |
336 | # Enabling partition with child cpusets is allowed | |
105f3fe9 | 337 | " C0-1:S+ C1 . C2-3 P1 . . . 0 A1:0-1,A2:1 A1:P1" |
a8c52eba WL |
338 | |
339 | # A partition root with non-partition root parent is invalid, but it | |
340 | # can be made valid if its parent becomes a partition root too. | |
105f3fe9 WL |
341 | " C0-1:S+ C1 . C2-3 . P2 . . 0 A1:0-1,A2:1 A1:P0,A2:P-2" |
342 | " C0-1:S+ C1:P2 . C2-3 P1 . . . 0 A1:0,A2:1 A1:P1,A2:P2" | |
a8c52eba WL |
343 | |
344 | # A non-exclusive cpuset.cpus change will invalidate partition and its siblings | |
105f3fe9 WL |
345 | " C0-1:P1 . . C2-3 C0-2 . . . 0 A1:0-2,B1:2-3 A1:P-1,B1:P0" |
346 | " C0-1:P1 . . P1:C2-3 C0-2 . . . 0 A1:0-2,B1:2-3 A1:P-1,B1:P-1" | |
347 | " C0-1 . . P1:C2-3 C0-2 . . . 0 A1:0-2,B1:2-3 A1:P0,B1:P-1" | |
a8c52eba | 348 | |
105f3fe9 WL |
349 | # old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS |
350 | # ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ -------- | |
a8c52eba WL |
351 | # Failure cases: |
352 | ||
353 | # A task cannot be added to a partition with no cpu | |
105f3fe9 WL |
354 | "C2-3:P1:S+ C3:P1 . . O2=0:T . . . 1 A1:,A2:3 A1:P1,A2:P1" |
355 | ||
356 | # Changes to cpuset.cpus.exclusive that violate exclusivity rule is rejected | |
357 | " C0-3 . . C4-5 X0-3 . . X3-5 1 A1:0-3,B1:4-5" | |
a8c52eba WL |
358 | ) |
359 | ||
360 | # | |
361 | # Write to the cpu online file | |
105f3fe9 | 362 | # $1 - <c>=<v> where <c> = cpu number, <v> value to be written |
a8c52eba WL |
363 | # |
364 | write_cpu_online() | |
365 | { | |
105f3fe9 WL |
366 | CPU=${1%=*} |
367 | VAL=${1#*=} | |
a8c52eba WL |
368 | CPUFILE=//sys/devices/system/cpu/cpu${CPU}/online |
369 | if [[ $VAL -eq 0 ]] | |
370 | then | |
371 | OFFLINE_CPUS="$OFFLINE_CPUS $CPU" | |
372 | else | |
373 | [[ -n "$OFFLINE_CPUS" ]] && { | |
374 | OFFLINE_CPUS=$(echo $CPU $CPU $OFFLINE_CPUS | fmt -1 |\ | |
375 | sort | uniq -u) | |
376 | } | |
377 | fi | |
378 | echo $VAL > $CPUFILE | |
72c6303a | 379 | pause 0.05 |
a8c52eba WL |
380 | } |
381 | ||
382 | # | |
383 | # Set controller state | |
384 | # $1 - cgroup directory | |
385 | # $2 - state | |
386 | # $3 - showerr | |
387 | # | |
388 | # The presence of ":" in state means transition from one to the next. | |
389 | # | |
390 | set_ctrl_state() | |
391 | { | |
392 | TMPMSG=/tmp/.msg_$$ | |
393 | CGRP=$1 | |
394 | STATE=$2 | |
105f3fe9 | 395 | SHOWERR=${3} |
a8c52eba WL |
396 | CTRL=${CTRL:=$CONTROLLER} |
397 | HASERR=0 | |
398 | REDIRECT="2> $TMPMSG" | |
399 | [[ -z "$STATE" || "$STATE" = '.' ]] && return 0 | |
105f3fe9 | 400 | [[ $VERBOSE -gt 0 ]] && SHOWERR=1 |
a8c52eba WL |
401 | |
402 | rm -f $TMPMSG | |
403 | for CMD in $(echo $STATE | sed -e "s/:/ /g") | |
404 | do | |
405 | TFILE=$CGRP/cgroup.procs | |
406 | SFILE=$CGRP/cgroup.subtree_control | |
407 | PFILE=$CGRP/cpuset.cpus.partition | |
408 | CFILE=$CGRP/cpuset.cpus | |
105f3fe9 | 409 | XFILE=$CGRP/cpuset.cpus.exclusive |
a8c52eba WL |
410 | S=$(expr substr $CMD 1 1) |
411 | if [[ $S = S ]] | |
412 | then | |
413 | PREFIX=${CMD#?} | |
414 | COMM="echo ${PREFIX}${CTRL} > $SFILE" | |
415 | eval $COMM $REDIRECT | |
105f3fe9 WL |
416 | elif [[ $S = X ]] |
417 | then | |
418 | CPUS=${CMD#?} | |
419 | COMM="echo $CPUS > $XFILE" | |
420 | eval $COMM $REDIRECT | |
a8c52eba WL |
421 | elif [[ $S = C ]] |
422 | then | |
423 | CPUS=${CMD#?} | |
424 | COMM="echo $CPUS > $CFILE" | |
425 | eval $COMM $REDIRECT | |
426 | elif [[ $S = P ]] | |
427 | then | |
428 | VAL=${CMD#?} | |
429 | case $VAL in | |
430 | 0) VAL=member | |
431 | ;; | |
432 | 1) VAL=root | |
433 | ;; | |
434 | 2) VAL=isolated | |
435 | ;; | |
436 | *) | |
437 | echo "Invalid partition state - $VAL" | |
438 | exit 1 | |
439 | ;; | |
440 | esac | |
441 | COMM="echo $VAL > $PFILE" | |
442 | eval $COMM $REDIRECT | |
443 | elif [[ $S = O ]] | |
444 | then | |
445 | VAL=${CMD#?} | |
446 | write_cpu_online $VAL | |
447 | elif [[ $S = T ]] | |
448 | then | |
449 | COMM="echo 0 > $TFILE" | |
450 | eval $COMM $REDIRECT | |
451 | fi | |
452 | RET=$? | |
453 | [[ $RET -ne 0 ]] && { | |
454 | [[ -n "$SHOWERR" ]] && { | |
455 | echo "$COMM" | |
456 | cat $TMPMSG | |
457 | } | |
458 | HASERR=1 | |
459 | } | |
460 | pause 0.01 | |
461 | rm -f $TMPMSG | |
462 | done | |
463 | return $HASERR | |
464 | } | |
465 | ||
466 | set_ctrl_state_noerr() | |
467 | { | |
468 | CGRP=$1 | |
469 | STATE=$2 | |
470 | [[ -d $CGRP ]] || mkdir $CGRP | |
471 | set_ctrl_state $CGRP $STATE 1 | |
472 | [[ $? -ne 0 ]] && { | |
473 | echo "ERROR: Failed to set $2 to cgroup $1!" | |
474 | exit 1 | |
475 | } | |
476 | } | |
477 | ||
478 | online_cpus() | |
479 | { | |
480 | [[ -n "OFFLINE_CPUS" ]] && { | |
481 | for C in $OFFLINE_CPUS | |
482 | do | |
105f3fe9 | 483 | write_cpu_online ${C}=1 |
a8c52eba WL |
484 | done |
485 | } | |
486 | } | |
487 | ||
488 | # | |
489 | # Return 1 if the list of effective cpus isn't the same as the initial list. | |
490 | # | |
491 | reset_cgroup_states() | |
492 | { | |
493 | echo 0 > $CGROUP2/cgroup.procs | |
494 | online_cpus | |
495 | rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1 | |
105f3fe9 WL |
496 | pause 0.02 |
497 | set_ctrl_state . R- | |
a8c52eba WL |
498 | pause 0.01 |
499 | } | |
500 | ||
501 | dump_states() | |
502 | { | |
105f3fe9 | 503 | for DIR in . A1 A1/A2 A1/A2/A3 B1 |
a8c52eba | 504 | do |
105f3fe9 | 505 | CPUS=$DIR/cpuset.cpus |
a8c52eba | 506 | ECPUS=$DIR/cpuset.cpus.effective |
105f3fe9 WL |
507 | XCPUS=$DIR/cpuset.cpus.exclusive |
508 | XECPUS=$DIR/cpuset.cpus.exclusive.effective | |
a8c52eba | 509 | PRS=$DIR/cpuset.cpus.partition |
105f3fe9 | 510 | PCPUS=$DIR/.__DEBUG__.cpuset.cpus.subpartitions |
877c737d | 511 | ISCPUS=$DIR/cpuset.cpus.isolated |
105f3fe9 WL |
512 | [[ -e $CPUS ]] && echo "$CPUS: $(cat $CPUS)" |
513 | [[ -e $XCPUS ]] && echo "$XCPUS: $(cat $XCPUS)" | |
514 | [[ -e $ECPUS ]] && echo "$ECPUS: $(cat $ECPUS)" | |
515 | [[ -e $XECPUS ]] && echo "$XECPUS: $(cat $XECPUS)" | |
516 | [[ -e $PRS ]] && echo "$PRS: $(cat $PRS)" | |
517 | [[ -e $PCPUS ]] && echo "$PCPUS: $(cat $PCPUS)" | |
72c6303a | 518 | [[ -e $ISCPUS ]] && echo "$ISCPUS: $(cat $ISCPUS)" |
a8c52eba WL |
519 | done |
520 | } | |
521 | ||
522 | # | |
523 | # Check effective cpus | |
524 | # $1 - check string, format: <cgroup>:<cpu-list>[,<cgroup>:<cpu-list>]* | |
525 | # | |
526 | check_effective_cpus() | |
527 | { | |
528 | CHK_STR=$1 | |
529 | for CHK in $(echo $CHK_STR | sed -e "s/,/ /g") | |
530 | do | |
531 | set -- $(echo $CHK | sed -e "s/:/ /g") | |
532 | CGRP=$1 | |
533 | CPUS=$2 | |
105f3fe9 WL |
534 | if [[ $CGRP = X* ]] |
535 | then | |
536 | CGRP=${CGRP#X} | |
537 | FILE=cpuset.cpus.exclusive.effective | |
538 | else | |
539 | FILE=cpuset.cpus.effective | |
540 | fi | |
a8c52eba WL |
541 | [[ $CGRP = A2 ]] && CGRP=A1/A2 |
542 | [[ $CGRP = A3 ]] && CGRP=A1/A2/A3 | |
105f3fe9 WL |
543 | [[ -e $CGRP/$FILE ]] || return 1 |
544 | [[ $CPUS = $(cat $CGRP/$FILE) ]] || return 1 | |
a8c52eba WL |
545 | done |
546 | } | |
547 | ||
548 | # | |
549 | # Check cgroup states | |
550 | # $1 - check string, format: <cgroup>:<state>[,<cgroup>:<state>]* | |
551 | # | |
552 | check_cgroup_states() | |
553 | { | |
554 | CHK_STR=$1 | |
555 | for CHK in $(echo $CHK_STR | sed -e "s/,/ /g") | |
556 | do | |
557 | set -- $(echo $CHK | sed -e "s/:/ /g") | |
558 | CGRP=$1 | |
559 | STATE=$2 | |
560 | FILE= | |
561 | EVAL=$(expr substr $STATE 2 2) | |
562 | [[ $CGRP = A2 ]] && CGRP=A1/A2 | |
563 | [[ $CGRP = A3 ]] && CGRP=A1/A2/A3 | |
564 | ||
565 | case $STATE in | |
566 | P*) FILE=$CGRP/cpuset.cpus.partition | |
567 | ;; | |
568 | *) echo "Unknown state: $STATE!" | |
569 | exit 1 | |
570 | ;; | |
571 | esac | |
572 | VAL=$(cat $FILE) | |
573 | ||
574 | case "$VAL" in | |
575 | member) VAL=0 | |
576 | ;; | |
577 | root) VAL=1 | |
578 | ;; | |
579 | isolated) | |
580 | VAL=2 | |
581 | ;; | |
582 | "root invalid"*) | |
583 | VAL=-1 | |
584 | ;; | |
585 | "isolated invalid"*) | |
586 | VAL=-2 | |
587 | ;; | |
588 | esac | |
589 | [[ $EVAL != $VAL ]] && return 1 | |
590 | done | |
591 | return 0 | |
592 | } | |
593 | ||
105f3fe9 WL |
594 | # |
595 | # Get isolated (including offline) CPUs by looking at | |
877c737d | 596 | # /sys/kernel/debug/sched/domains and cpuset.cpus.isolated control file, |
72c6303a | 597 | # if available, and compare that with the expected value. |
105f3fe9 | 598 | # |
72c6303a WL |
599 | # Note that isolated CPUs from the sched/domains context include offline |
600 | # CPUs as well as CPUs in non-isolated 1-CPU partition. Those CPUs may | |
877c737d | 601 | # not be included in the cpuset.cpus.isolated control file which contains |
72c6303a | 602 | # only CPUs in isolated partitions. |
105f3fe9 | 603 | # |
72c6303a WL |
604 | # $1 - expected isolated cpu list(s) <isolcpus1>{,<isolcpus2>} |
605 | # <isolcpus1> - expected sched/domains value | |
877c737d | 606 | # <isolcpus2> - cpuset.cpus.isolated value = <isolcpus1> if not defined |
105f3fe9 WL |
607 | # |
608 | check_isolcpus() | |
609 | { | |
610 | EXPECT_VAL=$1 | |
611 | ISOLCPUS= | |
612 | LASTISOLCPU= | |
613 | SCHED_DOMAINS=/sys/kernel/debug/sched/domains | |
877c737d | 614 | ISCPUS=${CGROUP2}/cpuset.cpus.isolated |
72c6303a WL |
615 | if [[ $EXPECT_VAL = . ]] |
616 | then | |
617 | EXPECT_VAL= | |
618 | EXPECT_VAL2= | |
619 | elif [[ $(expr $EXPECT_VAL : ".*,.*") > 0 ]] | |
620 | then | |
621 | set -- $(echo $EXPECT_VAL | sed -e "s/,/ /g") | |
622 | EXPECT_VAL=$1 | |
623 | EXPECT_VAL2=$2 | |
624 | else | |
625 | EXPECT_VAL2=$EXPECT_VAL | |
626 | fi | |
627 | ||
628 | # | |
629 | # Check the debug isolated cpumask, if present | |
630 | # | |
631 | [[ -f $ISCPUS ]] && { | |
632 | ISOLCPUS=$(cat $ISCPUS) | |
633 | [[ "$EXPECT_VAL2" != "$ISOLCPUS" ]] && { | |
634 | # Take a 50ms pause and try again | |
635 | pause 0.05 | |
636 | ISOLCPUS=$(cat $ISCPUS) | |
637 | } | |
638 | [[ "$EXPECT_VAL2" != "$ISOLCPUS" ]] && return 1 | |
639 | ISOLCPUS= | |
640 | } | |
641 | ||
642 | # | |
643 | # Use the sched domain in debugfs to check isolated CPUs, if available | |
644 | # | |
105f3fe9 | 645 | [[ -d $SCHED_DOMAINS ]] || return 0 |
105f3fe9 WL |
646 | |
647 | for ((CPU=0; CPU < $NR_CPUS; CPU++)) | |
648 | do | |
649 | [[ -n "$(ls ${SCHED_DOMAINS}/cpu$CPU)" ]] && continue | |
650 | ||
651 | if [[ -z "$LASTISOLCPU" ]] | |
652 | then | |
653 | ISOLCPUS=$CPU | |
654 | LASTISOLCPU=$CPU | |
655 | elif [[ "$LASTISOLCPU" -eq $((CPU - 1)) ]] | |
656 | then | |
657 | echo $ISOLCPUS | grep -q "\<$LASTISOLCPU\$" | |
658 | if [[ $? -eq 0 ]] | |
659 | then | |
660 | ISOLCPUS=${ISOLCPUS}- | |
661 | fi | |
662 | LASTISOLCPU=$CPU | |
663 | else | |
664 | if [[ $ISOLCPUS = *- ]] | |
665 | then | |
666 | ISOLCPUS=${ISOLCPUS}$LASTISOLCPU | |
667 | fi | |
668 | ISOLCPUS=${ISOLCPUS},$CPU | |
669 | LASTISOLCPU=$CPU | |
670 | fi | |
671 | done | |
672 | [[ "$ISOLCPUS" = *- ]] && ISOLCPUS=${ISOLCPUS}$LASTISOLCPU | |
673 | [[ "$EXPECT_VAL" = "$ISOLCPUS" ]] | |
674 | } | |
675 | ||
676 | test_fail() | |
677 | { | |
678 | TESTNUM=$1 | |
679 | TESTTYPE=$2 | |
680 | ADDINFO=$3 | |
681 | echo "Test $TEST[$TESTNUM] failed $TESTTYPE check!" | |
682 | [[ -n "$ADDINFO" ]] && echo "*** $ADDINFO ***" | |
683 | eval echo \${$TEST[$I]} | |
684 | echo | |
685 | dump_states | |
686 | exit 1 | |
687 | } | |
688 | ||
72c6303a WL |
689 | # |
690 | # Check to see if there are unexpected isolated CPUs left | |
691 | # | |
692 | null_isolcpus_check() | |
693 | { | |
694 | [[ $VERBOSE -gt 0 ]] || return 0 | |
877c737d WL |
695 | # Retry a few times before printing error |
696 | RETRY=0 | |
697 | while [[ $RETRY -lt 5 ]] | |
698 | do | |
699 | pause 0.01 | |
700 | check_isolcpus "." | |
701 | [[ $? -eq 0 ]] && return 0 | |
702 | ((RETRY++)) | |
703 | done | |
704 | echo "Unexpected isolated CPUs: $ISOLCPUS" | |
705 | dump_states | |
706 | exit 1 | |
72c6303a WL |
707 | } |
708 | ||
a8c52eba WL |
709 | # |
710 | # Run cpuset state transition test | |
711 | # $1 - test matrix name | |
712 | # | |
713 | # This test is somewhat fragile as delays (sleep x) are added in various | |
714 | # places to make sure state changes are fully propagated before the next | |
715 | # action. These delays may need to be adjusted if running in a slower machine. | |
716 | # | |
717 | run_state_test() | |
718 | { | |
719 | TEST=$1 | |
720 | CONTROLLER=cpuset | |
a8c52eba WL |
721 | I=0 |
722 | eval CNT="\${#$TEST[@]}" | |
723 | ||
724 | reset_cgroup_states | |
a8c52eba WL |
725 | console_msg "Running state transition test ..." |
726 | ||
727 | while [[ $I -lt $CNT ]] | |
728 | do | |
729 | echo "Running test $I ..." > /dev/console | |
105f3fe9 WL |
730 | [[ $VERBOSE -gt 1 ]] && { |
731 | echo "" | |
732 | eval echo \${$TEST[$I]} | |
733 | } | |
a8c52eba | 734 | eval set -- "\${$TEST[$I]}" |
105f3fe9 WL |
735 | OLD_A1=$1 |
736 | OLD_A2=$2 | |
737 | OLD_A3=$3 | |
738 | OLD_B1=$4 | |
739 | NEW_A1=$5 | |
740 | NEW_A2=$6 | |
741 | NEW_A3=$7 | |
742 | NEW_B1=$8 | |
743 | RESULT=$9 | |
744 | ECPUS=${10} | |
745 | STATES=${11} | |
746 | ICPUS=${12} | |
747 | ||
748 | set_ctrl_state_noerr B1 $OLD_B1 | |
a8c52eba WL |
749 | set_ctrl_state_noerr A1 $OLD_A1 |
750 | set_ctrl_state_noerr A1/A2 $OLD_A2 | |
751 | set_ctrl_state_noerr A1/A2/A3 $OLD_A3 | |
a8c52eba WL |
752 | RETVAL=0 |
753 | set_ctrl_state A1 $NEW_A1; ((RETVAL += $?)) | |
754 | set_ctrl_state A1/A2 $NEW_A2; ((RETVAL += $?)) | |
755 | set_ctrl_state A1/A2/A3 $NEW_A3; ((RETVAL += $?)) | |
756 | set_ctrl_state B1 $NEW_B1; ((RETVAL += $?)) | |
757 | ||
105f3fe9 | 758 | [[ $RETVAL -ne $RESULT ]] && test_fail $I result |
a8c52eba WL |
759 | |
760 | [[ -n "$ECPUS" && "$ECPUS" != . ]] && { | |
761 | check_effective_cpus $ECPUS | |
105f3fe9 | 762 | [[ $? -ne 0 ]] && test_fail $I "effective CPU" |
a8c52eba WL |
763 | } |
764 | ||
105f3fe9 | 765 | [[ -n "$STATES" && "$STATES" != . ]] && { |
a8c52eba | 766 | check_cgroup_states $STATES |
105f3fe9 | 767 | [[ $? -ne 0 ]] && test_fail $I states |
a8c52eba WL |
768 | } |
769 | ||
105f3fe9 WL |
770 | # Compare the expected isolated CPUs with the actual ones, |
771 | # if available | |
772 | [[ -n "$ICPUS" ]] && { | |
773 | check_isolcpus $ICPUS | |
774 | [[ $? -ne 0 ]] && test_fail $I "isolated CPU" \ | |
775 | "Expect $ICPUS, get $ISOLCPUS instead" | |
776 | } | |
a8c52eba WL |
777 | reset_cgroup_states |
778 | # | |
779 | # Check to see if effective cpu list changes | |
780 | # | |
a8c52eba | 781 | NEWLIST=$(cat cpuset.cpus.effective) |
105f3fe9 | 782 | RETRY=0 |
877c737d | 783 | while [[ $NEWLIST != $CPULIST && $RETRY -lt 8 ]] |
105f3fe9 WL |
784 | do |
785 | # Wait a bit longer & recheck a few times | |
786 | pause 0.01 | |
787 | ((RETRY++)) | |
788 | NEWLIST=$(cat cpuset.cpus.effective) | |
789 | done | |
a8c52eba WL |
790 | [[ $NEWLIST != $CPULIST ]] && { |
791 | echo "Effective cpus changed to $NEWLIST after test $I!" | |
792 | exit 1 | |
793 | } | |
72c6303a | 794 | null_isolcpus_check |
105f3fe9 | 795 | [[ $VERBOSE -gt 0 ]] && echo "Test $I done." |
a8c52eba WL |
796 | ((I++)) |
797 | done | |
798 | echo "All $I tests of $TEST PASSED." | |
a8c52eba WL |
799 | } |
800 | ||
14060dfc WL |
801 | # |
802 | # Testing the new "isolated" partition root type | |
803 | # | |
804 | test_isolated() | |
805 | { | |
806 | cd $CGROUP2/test | |
807 | echo 2-3 > cpuset.cpus | |
808 | TYPE=$(cat cpuset.cpus.partition) | |
809 | [[ $TYPE = member ]] || echo member > cpuset.cpus.partition | |
810 | ||
811 | console_msg "Change from member to root" | |
812 | test_partition root | |
813 | ||
814 | console_msg "Change from root to isolated" | |
815 | test_partition isolated | |
816 | ||
817 | console_msg "Change from isolated to member" | |
818 | test_partition member | |
819 | ||
820 | console_msg "Change from member to isolated" | |
821 | test_partition isolated | |
822 | ||
823 | console_msg "Change from isolated to root" | |
824 | test_partition root | |
825 | ||
826 | console_msg "Change from root to member" | |
827 | test_partition member | |
828 | ||
829 | # | |
830 | # Testing partition root with no cpu | |
831 | # | |
832 | console_msg "Distribute all cpus to child partition" | |
833 | echo +cpuset > cgroup.subtree_control | |
834 | test_partition root | |
835 | ||
836 | mkdir A1 | |
837 | cd A1 | |
838 | echo 2-3 > cpuset.cpus | |
839 | test_partition root | |
840 | test_effective_cpus 2-3 | |
841 | cd .. | |
842 | test_effective_cpus "" | |
843 | ||
844 | console_msg "Moving task to partition test" | |
845 | test_add_proc "No space left" | |
846 | cd A1 | |
847 | test_add_proc "" | |
848 | cd .. | |
849 | ||
850 | console_msg "Shrink and expand child partition" | |
851 | cd A1 | |
852 | echo 2 > cpuset.cpus | |
853 | cd .. | |
854 | test_effective_cpus 3 | |
855 | cd A1 | |
856 | echo 2-3 > cpuset.cpus | |
857 | cd .. | |
858 | test_effective_cpus "" | |
859 | ||
860 | # Cleaning up | |
861 | console_msg "Cleaning up" | |
862 | echo $$ > $CGROUP2/cgroup.procs | |
863 | [[ -d A1 ]] && rmdir A1 | |
72c6303a | 864 | null_isolcpus_check |
14060dfc WL |
865 | } |
866 | ||
a8c52eba WL |
867 | # |
868 | # Wait for inotify event for the given file and read it | |
869 | # $1: cgroup file to wait for | |
870 | # $2: file to store the read result | |
871 | # | |
872 | wait_inotify() | |
873 | { | |
874 | CGROUP_FILE=$1 | |
875 | OUTPUT_FILE=$2 | |
876 | ||
877 | $WAIT_INOTIFY $CGROUP_FILE | |
878 | cat $CGROUP_FILE > $OUTPUT_FILE | |
879 | } | |
880 | ||
881 | # | |
882 | # Test if inotify events are properly generated when going into and out of | |
883 | # invalid partition state. | |
884 | # | |
885 | test_inotify() | |
886 | { | |
887 | ERR=0 | |
888 | PRS=/tmp/.prs_$$ | |
105f3fe9 | 889 | cd $CGROUP2/test |
a8c52eba WL |
890 | [[ -f $WAIT_INOTIFY ]] || { |
891 | echo "wait_inotify not found, inotify test SKIPPED." | |
892 | return | |
893 | } | |
894 | ||
895 | pause 0.01 | |
896 | echo 1 > cpuset.cpus | |
897 | echo 0 > cgroup.procs | |
898 | echo root > cpuset.cpus.partition | |
899 | pause 0.01 | |
900 | rm -f $PRS | |
901 | wait_inotify $PWD/cpuset.cpus.partition $PRS & | |
902 | pause 0.01 | |
105f3fe9 | 903 | set_ctrl_state . "O1=0" |
a8c52eba WL |
904 | pause 0.01 |
905 | check_cgroup_states ".:P-1" | |
906 | if [[ $? -ne 0 ]] | |
907 | then | |
908 | echo "FAILED: Inotify test - partition not invalid" | |
909 | ERR=1 | |
910 | elif [[ ! -f $PRS ]] | |
911 | then | |
912 | echo "FAILED: Inotify test - event not generated" | |
913 | ERR=1 | |
914 | kill %1 | |
915 | elif [[ $(cat $PRS) != "root invalid"* ]] | |
916 | then | |
917 | echo "FAILED: Inotify test - incorrect state" | |
918 | cat $PRS | |
919 | ERR=1 | |
920 | fi | |
921 | online_cpus | |
922 | echo member > cpuset.cpus.partition | |
923 | echo 0 > ../cgroup.procs | |
924 | if [[ $ERR -ne 0 ]] | |
925 | then | |
926 | exit 1 | |
927 | else | |
928 | echo "Inotify test PASSED" | |
929 | fi | |
930 | } | |
931 | ||
1e85591d | 932 | trap cleanup 0 2 3 6 |
a8c52eba WL |
933 | run_state_test TEST_MATRIX |
934 | test_isolated | |
935 | test_inotify | |
936 | echo "All tests PASSED." |