xref: /xnu-11215.61.5/tests/ktrace/kdebug_coproc_tests.c (revision 4f1223e81cd707a65cc109d0b8ad6653699da3c4)
1*4f1223e8SApple OSS Distributions // Copyright (c) 2020 Apple Inc.  All rights reserved.
2*4f1223e8SApple OSS Distributions 
3*4f1223e8SApple OSS Distributions #include <darwintest.h>
4*4f1223e8SApple OSS Distributions #include <darwintest_utils.h>
5*4f1223e8SApple OSS Distributions #include <dispatch/dispatch.h>
6*4f1223e8SApple OSS Distributions #include <inttypes.h>
7*4f1223e8SApple OSS Distributions #include <ktrace/session.h>
8*4f1223e8SApple OSS Distributions #include <ktrace/private.h>
9*4f1223e8SApple OSS Distributions #include <kperf/kperf.h>
10*4f1223e8SApple OSS Distributions #include <stdlib.h>
11*4f1223e8SApple OSS Distributions #include <sys/kdebug.h>
12*4f1223e8SApple OSS Distributions #include <sys/kdebug_private.h>
13*4f1223e8SApple OSS Distributions #include <sys/sysctl.h>
14*4f1223e8SApple OSS Distributions #include <stdint.h>
15*4f1223e8SApple OSS Distributions 
16*4f1223e8SApple OSS Distributions #include "ktrace_helpers.h"
17*4f1223e8SApple OSS Distributions #include "test_utils.h"
18*4f1223e8SApple OSS Distributions #include "ktrace_meta.h"
19*4f1223e8SApple OSS Distributions 
20*4f1223e8SApple OSS Distributions static const uint32_t frame_eventid = KDBG_EVENTID(DBG_BSD,
21*4f1223e8SApple OSS Distributions     DBG_BSD_KDEBUG_TEST, 1);
22*4f1223e8SApple OSS Distributions 
23*4f1223e8SApple OSS Distributions static ktrace_session_t
future_events_session(void)24*4f1223e8SApple OSS Distributions future_events_session(void)
25*4f1223e8SApple OSS Distributions {
26*4f1223e8SApple OSS Distributions 	ktrace_session_t ktsess = ktrace_session_create();
27*4f1223e8SApple OSS Distributions 	T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(ktsess, "failed to create session");
28*4f1223e8SApple OSS Distributions 
29*4f1223e8SApple OSS Distributions 	ktrace_events_single(ktsess, KDBG_EVENTID(DBG_BSD, DBG_BSD_KDEBUG_TEST, 0),
30*4f1223e8SApple OSS Distributions 	    ^(struct trace_point *tp __unused) {
31*4f1223e8SApple OSS Distributions 		T_FAIL("saw future test event from IOP");
32*4f1223e8SApple OSS Distributions 	});
33*4f1223e8SApple OSS Distributions 	ktrace_events_single(ktsess, frame_eventid, ^(struct trace_point *tp) {
34*4f1223e8SApple OSS Distributions 		if (tp->debugid & DBG_FUNC_START) {
35*4f1223e8SApple OSS Distributions 			T_LOG("saw start event");
36*4f1223e8SApple OSS Distributions 		} else {
37*4f1223e8SApple OSS Distributions 			T_LOG("saw event traced after trying to trace future event, ending");
38*4f1223e8SApple OSS Distributions 			ktrace_end(ktsess, 1);
39*4f1223e8SApple OSS Distributions 		}
40*4f1223e8SApple OSS Distributions 	});
41*4f1223e8SApple OSS Distributions 
42*4f1223e8SApple OSS Distributions 	ktrace_set_collection_interval(ktsess, 100);
43*4f1223e8SApple OSS Distributions 	return ktsess;
44*4f1223e8SApple OSS Distributions }
45*4f1223e8SApple OSS Distributions 
46*4f1223e8SApple OSS Distributions T_DECL(future_iop_events,
47*4f1223e8SApple OSS Distributions     "make sure IOPs cannot trace events in the future while live tracing",
48*4f1223e8SApple OSS Distributions 	T_META_TAG_VM_NOT_PREFERRED)
49*4f1223e8SApple OSS Distributions {
50*4f1223e8SApple OSS Distributions 	start_controlling_ktrace();
51*4f1223e8SApple OSS Distributions 	ktrace_session_t ktsess = future_events_session();
52*4f1223e8SApple OSS Distributions 	ktrace_set_completion_handler(ktsess, ^{
53*4f1223e8SApple OSS Distributions 		ktrace_session_destroy(ktsess);
54*4f1223e8SApple OSS Distributions 		T_END;
55*4f1223e8SApple OSS Distributions 	});
56*4f1223e8SApple OSS Distributions 
57*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
58*4f1223e8SApple OSS Distributions 	    "start tracing");
59*4f1223e8SApple OSS Distributions 	kdebug_trace(frame_eventid | DBG_FUNC_START, 0, 0, 0, 0);
60*4f1223e8SApple OSS Distributions 	assert_kdebug_test(KDTEST_FUTURE_TIMESTAMP, "induce future times");
61*4f1223e8SApple OSS Distributions 	kdebug_trace(frame_eventid | DBG_FUNC_END, 0, 0, 0, 0);
62*4f1223e8SApple OSS Distributions 
63*4f1223e8SApple OSS Distributions 	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC),
64*4f1223e8SApple OSS Distributions 	    dispatch_get_main_queue(), ^{
65*4f1223e8SApple OSS Distributions 		T_FAIL("ending tracing after timeout");
66*4f1223e8SApple OSS Distributions 		ktrace_end(ktsess, 0);
67*4f1223e8SApple OSS Distributions 	});
68*4f1223e8SApple OSS Distributions 
69*4f1223e8SApple OSS Distributions 	dispatch_main();
70*4f1223e8SApple OSS Distributions }
71*4f1223e8SApple OSS Distributions 
72*4f1223e8SApple OSS Distributions T_DECL(future_iop_events_disabled,
73*4f1223e8SApple OSS Distributions     "make sure IOPs cannot trace events in the future after disabling tracing",
74*4f1223e8SApple OSS Distributions 	T_META_TAG_VM_NOT_PREFERRED)
75*4f1223e8SApple OSS Distributions {
76*4f1223e8SApple OSS Distributions 	start_controlling_ktrace();
77*4f1223e8SApple OSS Distributions 	ktrace_session_t ktsess = future_events_session();
78*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_configure(ktsess), "configure tracing");
79*4f1223e8SApple OSS Distributions 
80*4f1223e8SApple OSS Distributions 	kdebug_trace(frame_eventid | DBG_FUNC_START, 0, 0, 0, 0);
81*4f1223e8SApple OSS Distributions 	assert_kdebug_test(KDTEST_FUTURE_TIMESTAMP, "induce future times");
82*4f1223e8SApple OSS Distributions 	kdebug_trace(frame_eventid | DBG_FUNC_END, 0, 0, 0, 0);
83*4f1223e8SApple OSS Distributions 
84*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_disable_configured(ktsess),
85*4f1223e8SApple OSS Distributions 	    "disable tracing");
86*4f1223e8SApple OSS Distributions 	ktrace_session_destroy(ktsess);
87*4f1223e8SApple OSS Distributions 
88*4f1223e8SApple OSS Distributions 	ktsess = future_events_session();
89*4f1223e8SApple OSS Distributions 	T_QUIET;
90*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_set_use_existing(ktsess), "use existing trace");
91*4f1223e8SApple OSS Distributions 	ktrace_set_completion_handler(ktsess, ^{
92*4f1223e8SApple OSS Distributions 		ktrace_session_destroy(ktsess);
93*4f1223e8SApple OSS Distributions 		T_END;
94*4f1223e8SApple OSS Distributions 	});
95*4f1223e8SApple OSS Distributions 
96*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
97*4f1223e8SApple OSS Distributions 	    "start tracing existing session");
98*4f1223e8SApple OSS Distributions 
99*4f1223e8SApple OSS Distributions 	dispatch_main();
100*4f1223e8SApple OSS Distributions }
101*4f1223e8SApple OSS Distributions 
102*4f1223e8SApple OSS Distributions T_DECL(iop_events_disable,
103*4f1223e8SApple OSS Distributions     "make sure IOP events are flushed before disabling trace",
104*4f1223e8SApple OSS Distributions 	T_META_TAG_VM_PREFERRED)
105*4f1223e8SApple OSS Distributions {
106*4f1223e8SApple OSS Distributions 	start_controlling_ktrace();
107*4f1223e8SApple OSS Distributions 	ktrace_session_t ktsess = future_events_session();
108*4f1223e8SApple OSS Distributions 
109*4f1223e8SApple OSS Distributions 	assert_kdebug_test(KDTEST_SETUP_IOP, "setup sync flush IOP");
110*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_configure(ktsess), "configure tracing");
111*4f1223e8SApple OSS Distributions 
112*4f1223e8SApple OSS Distributions 	kdebug_trace(frame_eventid | DBG_FUNC_START, 0, 0, 0, 0);
113*4f1223e8SApple OSS Distributions 
114*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_disable_configured(ktsess),
115*4f1223e8SApple OSS Distributions 	    "disable tracing");
116*4f1223e8SApple OSS Distributions 	ktrace_session_destroy(ktsess);
117*4f1223e8SApple OSS Distributions 
118*4f1223e8SApple OSS Distributions 	ktsess = ktrace_session_create();
119*4f1223e8SApple OSS Distributions 	T_QUIET; T_WITH_ERRNO;
120*4f1223e8SApple OSS Distributions 	T_ASSERT_NOTNULL(ktsess, "create session");
121*4f1223e8SApple OSS Distributions 
122*4f1223e8SApple OSS Distributions 	ktrace_events_single(ktsess,
123*4f1223e8SApple OSS Distributions 	    KDBG_EVENTID(DBG_BSD, DBG_BSD_KDEBUG_TEST, 0xff),
124*4f1223e8SApple OSS Distributions 	    ^(struct trace_point *tp __unused) {
125*4f1223e8SApple OSS Distributions 		T_PASS("saw IOP event from sync flush");
126*4f1223e8SApple OSS Distributions 	});
127*4f1223e8SApple OSS Distributions 
128*4f1223e8SApple OSS Distributions 	T_QUIET;
129*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_set_use_existing(ktsess), "use existing trace");
130*4f1223e8SApple OSS Distributions 	ktrace_set_completion_handler(ktsess, ^{
131*4f1223e8SApple OSS Distributions 		ktrace_session_destroy(ktsess);
132*4f1223e8SApple OSS Distributions 		T_END;
133*4f1223e8SApple OSS Distributions 	});
134*4f1223e8SApple OSS Distributions 
135*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
136*4f1223e8SApple OSS Distributions 	    "start tracing existing session");
137*4f1223e8SApple OSS Distributions 
138*4f1223e8SApple OSS Distributions 	dispatch_main();
139*4f1223e8SApple OSS Distributions }
140*4f1223e8SApple OSS Distributions 
141*4f1223e8SApple OSS Distributions T_DECL(past_coproc_events,
142*4f1223e8SApple OSS Distributions     "make sure past events from coprocessors log a TRACE_PAST_EVENTS event",
143*4f1223e8SApple OSS Distributions 	T_META_TAG_VM_PREFERRED)
144*4f1223e8SApple OSS Distributions {
145*4f1223e8SApple OSS Distributions 	start_controlling_ktrace();
146*4f1223e8SApple OSS Distributions 	ktrace_session_t ktsess = future_events_session();
147*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_configure(ktsess), "configure tracing");
148*4f1223e8SApple OSS Distributions 
149*4f1223e8SApple OSS Distributions 	kdebug_trace(frame_eventid | DBG_FUNC_START, 0, 0, 0, 0);
150*4f1223e8SApple OSS Distributions 	assert_kdebug_test(KDTEST_PAST_EVENT, "induce past events");
151*4f1223e8SApple OSS Distributions 	kdebug_trace(frame_eventid | DBG_FUNC_END, 0, 0, 0, 0);
152*4f1223e8SApple OSS Distributions 
153*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_disable_configured(ktsess), "disable tracing");
154*4f1223e8SApple OSS Distributions 	ktrace_session_destroy(ktsess);
155*4f1223e8SApple OSS Distributions 
156*4f1223e8SApple OSS Distributions 	ktsess = future_events_session();
157*4f1223e8SApple OSS Distributions 	T_QUIET;
158*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_set_use_existing(ktsess), "use existing trace");
159*4f1223e8SApple OSS Distributions 	__block bool saw_past_event = false;
160*4f1223e8SApple OSS Distributions 	ktrace_events_single(ktsess, TRACE_PAST_EVENTS,
161*4f1223e8SApple OSS Distributions 			^(__unused ktrace_event_t event) {
162*4f1223e8SApple OSS Distributions 		saw_past_event = true;
163*4f1223e8SApple OSS Distributions 	});
164*4f1223e8SApple OSS Distributions 	ktrace_set_completion_handler(ktsess, ^{
165*4f1223e8SApple OSS Distributions 		ktrace_session_destroy(ktsess);
166*4f1223e8SApple OSS Distributions 		T_EXPECT_TRUE(saw_past_event, "saw past event");
167*4f1223e8SApple OSS Distributions 		T_END;
168*4f1223e8SApple OSS Distributions 	});
169*4f1223e8SApple OSS Distributions 
170*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
171*4f1223e8SApple OSS Distributions 	    "start tracing existing session");
172*4f1223e8SApple OSS Distributions 
173*4f1223e8SApple OSS Distributions 	dispatch_main();
174*4f1223e8SApple OSS Distributions }
175*4f1223e8SApple OSS Distributions 
176*4f1223e8SApple OSS Distributions static void
expect_convert_between_abs_cont(bool abs_to_cont)177*4f1223e8SApple OSS Distributions expect_convert_between_abs_cont(bool abs_to_cont)
178*4f1223e8SApple OSS Distributions {
179*4f1223e8SApple OSS Distributions 	uint64_t cur_abs_time, cur_cont_time;
180*4f1223e8SApple OSS Distributions 	kern_return_t kr = mach_get_times(&cur_abs_time, &cur_cont_time, NULL);
181*4f1223e8SApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_get_times");
182*4f1223e8SApple OSS Distributions 	bool hasnt_slept = cur_abs_time == cur_cont_time;
183*4f1223e8SApple OSS Distributions 	if (hasnt_slept) {
184*4f1223e8SApple OSS Distributions 		T_LOG("system hasn't slept, so continuous and absolute times are equal");
185*4f1223e8SApple OSS Distributions 		T_LOG("this test cannot ensure time conversions are done properly");
186*4f1223e8SApple OSS Distributions 	} else {
187*4f1223e8SApple OSS Distributions 		T_LOG("system has slept, times differ by %llu",
188*4f1223e8SApple OSS Distributions 		    cur_cont_time - cur_abs_time);
189*4f1223e8SApple OSS Distributions 	}
190*4f1223e8SApple OSS Distributions 
191*4f1223e8SApple OSS Distributions 	start_controlling_ktrace();
192*4f1223e8SApple OSS Distributions 	ktrace_session_t ktsess = ktrace_session_create();
193*4f1223e8SApple OSS Distributions 	ktrace_set_collection_interval(ktsess, 100);
194*4f1223e8SApple OSS Distributions 	if (abs_to_cont) {
195*4f1223e8SApple OSS Distributions 		ktrace_set_continuous_timestamps(ktsess, true);
196*4f1223e8SApple OSS Distributions 	}
197*4f1223e8SApple OSS Distributions 
198*4f1223e8SApple OSS Distributions 	__block bool found_abs_event = false;
199*4f1223e8SApple OSS Distributions 	__block bool found_cont_event = false;
200*4f1223e8SApple OSS Distributions 	const uint32_t abs_eventid = KDBG_EVENTID(DBG_BSD, DBG_BSD_KDEBUG_TEST, 0);
201*4f1223e8SApple OSS Distributions 	ktrace_events_single(ktsess, abs_eventid, ^(struct trace_point *tp) {
202*4f1223e8SApple OSS Distributions 		found_abs_event = true;
203*4f1223e8SApple OSS Distributions 		uint64_t arg_timestamp = (tp->arg1 & UINT32_MAX) | (tp->arg2 << 32);
204*4f1223e8SApple OSS Distributions 		if (abs_to_cont) {
205*4f1223e8SApple OSS Distributions 			if (hasnt_slept) {
206*4f1223e8SApple OSS Distributions 				T_MAYFAIL;
207*4f1223e8SApple OSS Distributions 			}
208*4f1223e8SApple OSS Distributions 			T_EXPECT_NE(tp->timestamp, arg_timestamp,
209*4f1223e8SApple OSS Distributions 			    "timestamp from absolute time IOP should be converted");
210*4f1223e8SApple OSS Distributions 		} else {
211*4f1223e8SApple OSS Distributions 			T_EXPECT_EQ(tp->timestamp, arg_timestamp,
212*4f1223e8SApple OSS Distributions 			    "timestamp from absolute time IOP should not be converted");
213*4f1223e8SApple OSS Distributions 		}
214*4f1223e8SApple OSS Distributions 		if (found_cont_event && found_abs_event) {
215*4f1223e8SApple OSS Distributions 			ktrace_end(ktsess, 1);
216*4f1223e8SApple OSS Distributions 		}
217*4f1223e8SApple OSS Distributions 	});
218*4f1223e8SApple OSS Distributions 
219*4f1223e8SApple OSS Distributions 	const uint32_t cont_eventid = KDBG_EVENTID(DBG_BSD, DBG_BSD_KDEBUG_TEST, 1);
220*4f1223e8SApple OSS Distributions 	ktrace_events_single(ktsess, cont_eventid, ^(struct trace_point *tp) {
221*4f1223e8SApple OSS Distributions 		found_cont_event = true;
222*4f1223e8SApple OSS Distributions 		uint64_t arg_timestamp = (tp->arg1 & UINT32_MAX) | (tp->arg2 << 32);
223*4f1223e8SApple OSS Distributions 		if (abs_to_cont) {
224*4f1223e8SApple OSS Distributions 			T_EXPECT_EQ(tp->timestamp, arg_timestamp,
225*4f1223e8SApple OSS Distributions 			    "timestamp from continuous time coprocessor should not be "
226*4f1223e8SApple OSS Distributions 			    "converted");
227*4f1223e8SApple OSS Distributions 		} else {
228*4f1223e8SApple OSS Distributions 			if (hasnt_slept) {
229*4f1223e8SApple OSS Distributions 				T_MAYFAIL;
230*4f1223e8SApple OSS Distributions 			}
231*4f1223e8SApple OSS Distributions 			T_EXPECT_NE(tp->timestamp, arg_timestamp,
232*4f1223e8SApple OSS Distributions 			    "timestamp from continuous time coprocessor should be "
233*4f1223e8SApple OSS Distributions 			    "converted");
234*4f1223e8SApple OSS Distributions 		}
235*4f1223e8SApple OSS Distributions 		if (found_cont_event && found_abs_event) {
236*4f1223e8SApple OSS Distributions 			ktrace_end(ktsess, 1);
237*4f1223e8SApple OSS Distributions 		}
238*4f1223e8SApple OSS Distributions 	});
239*4f1223e8SApple OSS Distributions 
240*4f1223e8SApple OSS Distributions 	ktrace_set_completion_handler(ktsess, ^{
241*4f1223e8SApple OSS Distributions 		T_EXPECT_TRUE(found_abs_event, "absolute time event present");
242*4f1223e8SApple OSS Distributions 		T_EXPECT_TRUE(found_cont_event, "continuous time event present");
243*4f1223e8SApple OSS Distributions 		ktrace_session_destroy(ktsess);
244*4f1223e8SApple OSS Distributions 		T_END;
245*4f1223e8SApple OSS Distributions 	});
246*4f1223e8SApple OSS Distributions 
247*4f1223e8SApple OSS Distributions 	assert_kdebug_test(KDTEST_SETUP_IOP, "setup sync flush IOP");
248*4f1223e8SApple OSS Distributions 	assert_kdebug_test(KDTEST_SETUP_COPROCESSOR, "setup coprocessor");
249*4f1223e8SApple OSS Distributions 
250*4f1223e8SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ktrace_start(ktsess, dispatch_get_main_queue()),
251*4f1223e8SApple OSS Distributions 	    "start tracing");
252*4f1223e8SApple OSS Distributions 	assert_kdebug_test(KDTEST_ABSOLUTE_TIMESTAMP, "induce absolute times");
253*4f1223e8SApple OSS Distributions 	assert_kdebug_test(KDTEST_CONTINUOUS_TIMESTAMP, "induce continuous times");
254*4f1223e8SApple OSS Distributions 	T_QUIET;
255*4f1223e8SApple OSS Distributions 	T_EXPECT_EQ(kdebug_using_continuous_time(), abs_to_cont,
256*4f1223e8SApple OSS Distributions 	    "should be using continuous time");
257*4f1223e8SApple OSS Distributions 
258*4f1223e8SApple OSS Distributions 	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC),
259*4f1223e8SApple OSS Distributions 	    dispatch_get_main_queue(), ^{
260*4f1223e8SApple OSS Distributions 		T_LOG("ending tracing after timeout");
261*4f1223e8SApple OSS Distributions 		ktrace_end(ktsess, 0);
262*4f1223e8SApple OSS Distributions 	});
263*4f1223e8SApple OSS Distributions }
264*4f1223e8SApple OSS Distributions 
265*4f1223e8SApple OSS Distributions T_DECL(absolute_to_continuous_iop,
266*4f1223e8SApple OSS Distributions     "expect IOPs issuing absolute times show up as continuous in the stream",
267*4f1223e8SApple OSS Distributions 	T_META_TAG_VM_PREFERRED)
268*4f1223e8SApple OSS Distributions {
269*4f1223e8SApple OSS Distributions 	expect_convert_between_abs_cont(true);
270*4f1223e8SApple OSS Distributions 	dispatch_main();
271*4f1223e8SApple OSS Distributions }
272*4f1223e8SApple OSS Distributions 
273*4f1223e8SApple OSS Distributions T_DECL(continuous_to_absolute_coproc,
274*4f1223e8SApple OSS Distributions     "expect IOPs issuing absolute times show up as continuous in the stream",
275*4f1223e8SApple OSS Distributions 	T_META_TAG_VM_PREFERRED)
276*4f1223e8SApple OSS Distributions {
277*4f1223e8SApple OSS Distributions 	expect_convert_between_abs_cont(false);
278*4f1223e8SApple OSS Distributions 	dispatch_main();
279*4f1223e8SApple OSS Distributions }
280