xref: /xnu-12377.61.12/tests/sched/zero_to_n_tests.c (revision 4d495c6e23c53686cf65f45067f79024cf5dcee8)
1 #include <darwintest.h>
2 #include <darwintest_utils.h>
3 #include <dispatch/dispatch.h>
4 #include <perfdata/perfdata.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdbool.h>
8 #include <errno.h>
9 #include "sched_test_utils.h"
10 #include "test_utils.h"
11 
12 T_GLOBAL_META(
13 	T_META_TAG_PERF,
14 	T_META_RUN_CONCURRENTLY(false),
15 	/* <rdar://137716223> */
16 	T_META_BOOTARGS_SET("enable_skstsct=1 cpu-dynamic-cluster-power-down=0"),
17 	T_META_CHECK_LEAKS(false),
18 	T_META_ASROOT(true),
19 	T_META_REQUIRES_SYSCTL_EQ("kern.hv_vmm_present", 0),
20 	T_META_NAMESPACE("xnu.scheduler"),
21 	T_META_RADAR_COMPONENT_NAME("xnu"),
22 	T_META_RADAR_COMPONENT_VERSION("scheduler"),
23 	T_META_OWNER("m_zinn"),
24 	T_META_TAG_VM_NOT_ELIGIBLE
25 	);
26 
27 static void
log_cmd(char ** cmd)28 log_cmd(char **cmd)
29 {
30 #define MAX_CMD_STR 1024
31 	char cmd_str[MAX_CMD_STR] = "";
32 	char *s;
33 
34 	while ((s = *cmd) != NULL) {
35 		strlcat(cmd_str, s, MAX_CMD_STR);
36 		strlcat(cmd_str, " ", MAX_CMD_STR);
37 		cmd++;
38 	}
39 	T_LOG("%s\n", cmd_str);
40 }
41 
42 static void
run_zn(char * name,char ** cmd,int argc,char * const argv[])43 run_zn(char *name, char **cmd, int argc, char *const argv[])
44 {
45 	log_cmd(cmd);
46 
47 	trace_handle_t trace = begin_collect_trace_fmt(COLLECT_TRACE_FLAG_DISABLE_SYSCALLS | COLLECT_TRACE_FLAG_DISABLE_CLUTCH, argc, argv, name);
48 
49 	__block bool test_failed = true;
50 	__block bool test_skipped = false;
51 	__block dispatch_semaphore_t stdout_finished_sem = dispatch_semaphore_create(0);
52 	T_QUIET; T_ASSERT_NOTNULL(stdout_finished_sem, "dispatch_semaphore_create()");
53 
54 	dt_launch_pipe_t *pipes = NULL;
55 	pid_t test_pid;
56 	test_pid = dt_launch_tool_pipe(cmd, false, &pipes, NULL, NULL, NULL, NULL);
57 	T_QUIET; T_ASSERT_NE(test_pid, 0, "dt_launch_tool_pipe() failed unexpectedly with errno %d", errno);
58 	T_QUIET; T_ASSERT_NOTNULL(pipes, "dt_launch_tool_pipe returned non-null pipes");
59 
60 	dispatch_block_t cleanup_handler =
61 	    ^{ dispatch_semaphore_signal(stdout_finished_sem); };
62 
63 	dt_pipe_data_handler_t stdout_handler = ^bool (char *data, __unused size_t data_size, __unused dt_pipe_data_handler_context_t *context) {
64 		T_LOG("%s", data);
65 		if (strstr(data, "TEST PASSED")) {
66 			test_failed = false;
67 			return true;
68 		}
69 		if (strstr(data, "TEST FAILED")) {
70 			test_failed = true;
71 			return true;
72 		}
73 		if (strstr(data, "TEST SKIPPED")) {
74 			test_skipped = true;
75 			return true;
76 		}
77 		return false;
78 	};
79 
80 	dt_pipe_data_handler_t stderr_handler = ^bool (char *data, __unused size_t data_size, __unused dt_pipe_data_handler_context_t *context) {
81 		T_LOG("%s", data);
82 		return false;
83 	};
84 
85 	dispatch_source_t stdout_reader = dt_create_dispatch_file_reader(pipes->pipe_out[0], BUFFER_PATTERN_LINE, stdout_handler, cleanup_handler, NULL);
86 	T_QUIET; T_ASSERT_NOTNULL(stdout_reader, "create darwintest dispatch file reader for stdout");
87 
88 	dispatch_source_t stderr_reader = dt_create_dispatch_file_reader(pipes->pipe_err[0], BUFFER_PATTERN_LINE, stderr_handler, ^{}, NULL);
89 	T_QUIET; T_ASSERT_NOTNULL(stderr_reader, "create darwintest dispatch file reader for stderr");
90 
91 	/* Wait for zero-to-n to exit, and check its return value. */
92 	int exitstatus;
93 	if (!dt_waitpid(test_pid, &exitstatus, NULL, 0) || exitstatus != 0) {
94 		T_FAIL("zero-to-n exitstatus=%d\n", exitstatus);
95 	}
96 
97 	/* Test exited, end the trace. */
98 	end_collect_trace(trace);
99 
100 	/* Wait for the readers to finish. */
101 	intptr_t rv = dispatch_semaphore_wait(stdout_finished_sem, dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC));
102 	T_QUIET; T_ASSERT_EQ((uint64_t) rv, 0ULL, "zn should finish within 30 seconds");
103 
104 	/* Free the pipes. */
105 	free(pipes);
106 
107 	if (test_skipped) {
108 		T_SKIP("%s", name);
109 	} else if (test_failed) {
110 		T_FAIL("%s", name);
111 	} else {
112 		T_PASS("%s", name);
113 	}
114 
115 	T_END;
116 }
117 
118 T_DECL(zn_rt, "Schedule 1 RT thread per performance core, and test max latency",
119     XNU_T_META_SOC_SPECIFIC)
120 {
121 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
122 		       "0", "broadcast-single-sem", "realtime", "1000",
123 		       "--spin-time", "200000",
124 		       "--spin-all",
125 		       "--test-rt",
126 #if defined(__arm64__)
127 		       "--bind", "P",     /* <rdar://137716223> */
128 		       "--trace", "500000",
129 #elif defined(__x86_64__)
130 		       "--trace", "2000000",
131 #endif
132 		       NULL};
133 
134 	run_zn("zn_rt", cmd, argc, argv);
135 }
136 
137 T_DECL(zn_rt_ival, "Schedule 1 RT thread per performance core, and test max latency",
138     XNU_T_META_SOC_SPECIFIC,
139     T_META_ENABLED(false) /* TODO: Enable once <rdar://145756951> is fixed. */)
140 {
141 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
142 		       "0", "broadcast-single-sem", "realtime", "1000",
143 		       "--spin-time", "200000",
144 		       "--spin-all",
145 		       "--test-rt",
146 		       "--rt-interval",
147 #if defined(__x86_64__)
148 		       "--trace", "2000000",
149 #else
150 		       "--trace", "500000",
151 #endif
152 		       NULL};
153 
154 	run_zn("zn_rt_ival", cmd, argc, argv);
155 }
156 
157 T_DECL(zn_rt_ival_ll, "Schedule 1 RT thread per performance core, and test max latency",
158     XNU_T_META_SOC_SPECIFIC)
159 {
160 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
161 		       "0", "broadcast-single-sem", "realtime", "1000",
162 		       "--spin-time", "200000",
163 		       "--spin-all",
164 		       "--test-rt",
165 		       "--rt-interval",
166 		       "--rt-ll",
167 #if defined(__x86_64__)
168 		       "--trace", "2000000",
169 #else
170 		       "--trace", "500000",
171 #endif
172 		       NULL};
173 
174 	run_zn("zn_rt_ival_ll", cmd, argc, argv);
175 }
176 
177 T_DECL(zn_rt_smt, "Schedule 1 RT thread per primary core, verify that the secondaries are idle iff the RT threads are running",
178     T_META_ENABLED(TARGET_CPU_X86_64))
179 {
180 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
181 		       "0", "broadcast-single-sem", "realtime", "1000",
182 		       "--spin-time", "200000",
183 		       "--spin-all",
184 		       "--churn-pri", "4",
185 		       "--test-rt-smt",
186 		       "--trace", "2000000",
187 		       NULL};
188 
189 	run_zn("zn_rt_smt", cmd, argc, argv);
190 }
191 
192 T_DECL(zn_rt_ival_smt, "Schedule 1 RT thread per primary core, verify that the secondaries are idle iff the RT threads are running",
193     T_META_ENABLED(TARGET_CPU_X86_64))
194 {
195 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
196 		       "0", "broadcast-single-sem", "realtime", "1000",
197 		       "--spin-time", "200000",
198 		       "--spin-all",
199 		       "--churn-pri", "4",
200 		       "--test-rt-smt",
201 		       "--rt-interval",
202 		       "--trace", "2000000",
203 		       NULL};
204 
205 	run_zn("zn_rt_ival_smt", cmd, argc, argv);
206 }
207 
208 T_DECL(zn_rt_avoid0, "Schedule 1 RT thread per primary core except for CPU 0",
209     T_META_ENABLED(TARGET_CPU_X86_64))
210 {
211 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
212 		       "0", "broadcast-single-sem", "realtime", "1000",
213 		       "--spin-time", "200000",
214 		       "--spin-all",
215 		       "--test-rt-avoid0",
216 		       "--trace", "2000000",
217 		       NULL};
218 
219 	run_zn("zn_rt_avoid0", cmd, argc, argv);
220 }
221 
222 T_DECL(zn_rt_ival_avoid0, "Schedule 1 RT thread per primary core except for CPU 0",
223     T_META_ENABLED(TARGET_CPU_X86_64))
224 {
225 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
226 		       "0", "broadcast-single-sem", "realtime", "1000",
227 		       "--spin-time", "200000",
228 		       "--spin-all",
229 		       "--test-rt-avoid0",
230 		       "--rt-interval",
231 		       "--trace", "2000000",
232 		       NULL};
233 
234 	run_zn("zn_rt_ival_avoid0", cmd, argc, argv);
235 }
236 
237 T_DECL(zn_rt_apt, "Emulate AVID Pro Tools with default latency deadlines")
238 {
239 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
240 		       "0", "chain", "realtime", "1000",
241 		       "--extra-thread-count", "-3",
242 		       "--spin-time", "200000",
243 		       "--spin-all",
244 		       "--churn-pri", "31", "--churn-random",
245 		       "--test-rt",
246 #if defined(__arm64__)
247 		       "--bind", "P",     /* <rdar://137716223> */
248 		       "--trace", "500000",
249 #elif defined(__x86_64__)
250 		       "--trace", "2000000",
251 #endif
252 		       NULL};
253 
254 	run_zn("zn_rt_apt", cmd, argc, argv);
255 }
256 
257 T_DECL(zn_rt_ival_apt, "Emulate AVID Pro Tools with default latency deadlines",
258     T_META_ENABLED(false) /* TODO: Enable once <rdar://145756951> is fixed. */)
259 {
260 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
261 		       "0", "chain", "realtime", "1000",
262 		       "--extra-thread-count", "-3",
263 		       "--spin-time", "200000",
264 		       "--spin-all",
265 		       "--churn-pri", "31", "--churn-random",
266 		       "--test-rt",
267 		       "--rt-interval",
268 #if defined(__x86_64__)
269 		       "--trace", "2000000",
270 #else
271 		       "--trace", "500000",
272 #endif
273 		       NULL};
274 
275 	run_zn("zn_rt_ival_apt", cmd, argc, argv);
276 }
277 
278 T_DECL(zn_rt_apt_ll, "Emulate AVID Pro Tools with low latency deadlines",
279     XNU_T_META_SOC_SPECIFIC)
280 {
281 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
282 		       "0", "chain", "realtime", "1000",
283 		       "--extra-thread-count", "-3",
284 		       "--spin-time", "200000",
285 		       "--spin-all",
286 		       "--churn-pri", "31", "--churn-random",
287 		       "--test-rt",
288 		       "--rt-ll",
289 #if defined(__arm64__)
290 		       "--bind", "P",     /* <rdar://137716223> */
291 #endif   /* __arm64__*/
292 		       "--trace", "500000",
293 		       NULL};
294 
295 	run_zn("zn_rt_apt_ll", cmd, argc, argv);
296 }
297 
298 T_DECL(zn_rt_ival_apt_ll, "Emulate AVID Pro Tools with low latency deadlines",
299     XNU_T_META_SOC_SPECIFIC)
300 {
301 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
302 		       "0", "chain", "realtime", "1000",
303 		       "--extra-thread-count", "-3",
304 		       "--spin-time", "200000",
305 		       "--spin-all",
306 		       "--churn-pri", "31", "--churn-random",
307 		       "--test-rt",
308 		       "--rt-ll",
309 		       "--rt-interval",
310 		       "--trace", "500000",
311 		       NULL};
312 
313 	run_zn("zn_rt_ival_apt_ll", cmd, argc, argv);
314 }
315 
316 T_DECL(zn_rt_edf, "Test max latency of earliest deadline RT threads in the presence of later deadline threads",
317     XNU_T_META_SOC_SPECIFIC)
318 {
319 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
320 		       "0", "broadcast-single-sem", "realtime", "1000",
321 		       "--extra-thread-count", "-1",
322 		       "--spin-time", "200000",
323 		       "--spin-all",
324 		       "--rt-churn",
325 		       "--test-rt",
326 #if defined(__arm64__)
327 		       "--bind", "P",     /* <rdar://137716223> */
328 		       "--trace", "500000",
329 #elif defined(__x86_64__)
330 		       "--trace", "2000000",
331 #endif
332 		       NULL};
333 
334 	run_zn("zn_rt_edf", cmd, argc, argv);
335 }
336 
337 T_DECL(zn_rt_ival_edf, "Test max latency of earliest deadline RT threads in the presence of later deadline threads",
338     XNU_T_META_SOC_SPECIFIC)
339 {
340 	char *cmd[] = {"/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
341 		       "0", "broadcast-single-sem", "realtime", "1000",
342 		       "--extra-thread-count", "-1",
343 		       "--spin-time", "200000",
344 		       "--spin-all",
345 		       "--rt-churn",
346 		       "--test-rt",
347 		       "--rt-ll",     /* TODO: remove low-latency constraint once <rdar://145756951> is fixed */
348 		       "--rt-interval",
349 #if defined(__x86_64__)
350 		       "--trace", "2000000",
351 #else
352 		       "--trace", "500000",
353 #endif
354 		       NULL};
355 
356 	run_zn("zn_rt_ival_edf", cmd, argc, argv);
357 }
358 
359