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