]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/darwintests/perf_kdebug.c
xnu-4570.51.1.tar.gz
[apple/xnu.git] / tools / tests / darwintests / perf_kdebug.c
1 #ifdef T_NAMESPACE
2 #undef T_NAMESPACE
3 #endif
4 #include <darwintest.h>
5
6 #include <sys/kdebug.h>
7 #include <sys/sysctl.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 T_GLOBAL_META(
13 T_META_NAMESPACE("xnu.perf.kdebug"),
14 T_META_ASROOT(true),
15 T_META_CHECK_LEAKS(false)
16 );
17
18 //
19 // Helper functions for direct control over the kernel trace facility.
20 //
21
22 static void _sysctl_reset() {
23 int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDREMOVE };
24 if(sysctl(mib, 3, NULL, NULL, NULL, 0)) {
25 T_FAIL("KERN_KDREMOVE sysctl failed");
26 }
27 }
28
29 static void _sysctl_setbuf(uint32_t capacity) {
30 int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDSETBUF, (int)capacity };
31 if (sysctl(mib, 4, NULL, NULL, NULL, 0)) {
32 T_FAIL("KERN_KDSETBUF sysctl failed");
33 }
34 }
35
36 static void _sysctl_setup() {
37 int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDSETUP };
38 if (sysctl(mib, 3, NULL, NULL, NULL, 0)) {
39 T_FAIL("KERN_KDSETUP sysctl failed");
40 }
41 }
42
43 static void _sysctl_enable(int value)
44 {
45 int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDENABLE, value };
46 if (sysctl(mib, 4, NULL, NULL, NULL, 0) < 0) {
47 T_FAIL("KERN_KDENABLE sysctl failed");
48 }
49 }
50
51 static void _sysctl_enable_typefilter(uint8_t* type_filter_bitmap) {
52 int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDSET_TYPEFILTER };
53 size_t needed = KDBG_TYPEFILTER_BITMAP_SIZE;
54 if(sysctl(mib, 3, type_filter_bitmap, &needed, NULL, 0)) {
55 T_FAIL("KERN_KDSET_TYPEFILTER sysctl failed");
56 }
57 }
58
59 static void _sysctl_nowrap(bool is_nowrap) {
60 int mib[] = { CTL_KERN, KERN_KDEBUG, is_nowrap ? KERN_KDEFLAGS : KERN_KDDFLAGS, KDBG_NOWRAP };
61 if (sysctl(mib, 4, NULL, NULL, NULL, 0)) {
62 T_FAIL("KDBG_NOWRAP sysctl failed");
63 }
64 }
65
66 static void enable_tracing(bool value) {
67 _sysctl_enable(value ? KDEBUG_ENABLE_TRACE : 0);
68 }
69
70 static void enable_typefilter_all_reject() {
71 uint8_t type_filter_bitmap[KDBG_TYPEFILTER_BITMAP_SIZE];
72 memset(type_filter_bitmap, 0, sizeof(type_filter_bitmap));
73 _sysctl_enable_typefilter(type_filter_bitmap);
74 }
75
76 static void enable_typefilter_all_pass() {
77 uint8_t type_filter_bitmap[KDBG_TYPEFILTER_BITMAP_SIZE];
78 memset(type_filter_bitmap, 0xff, sizeof(type_filter_bitmap));
79 _sysctl_enable_typefilter(type_filter_bitmap);
80 }
81
82 static void loop_kdebug_trace(dt_stat_time_t s) {
83 do {
84 dt_stat_token start = dt_stat_time_begin(s);
85 for (uint32_t i = 0; i<100; i++) {
86 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
87 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
88 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
89 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
90 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
91 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
92 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
93 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
94 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
95 kdebug_trace(0x97000000 | DBG_FUNC_NONE, i, i, i, i);
96 }
97 dt_stat_time_end_batch(s, 1000, start);
98 } while (!dt_stat_stable(s));
99 }
100
101 static void loop_getppid(dt_stat_time_t s) {
102 do {
103 dt_stat_token start = dt_stat_time_begin(s);
104 for (uint32_t i = 0; i<100; i++) {
105 getppid();
106 getppid();
107 getppid();
108 getppid();
109 getppid();
110 getppid();
111 getppid();
112 getppid();
113 getppid();
114 getppid();
115 }
116 dt_stat_time_end_batch(s, 1000, start);
117 } while (!dt_stat_stable(s));
118 }
119
120 static void reset_kdebug_trace(void) {
121 _sysctl_reset();
122 }
123
124 static void test(const char* test_name, void (^pretest_setup)(void), void (*test)(dt_stat_time_t s)) {
125 T_ATEND(reset_kdebug_trace);
126 _sysctl_reset();
127 _sysctl_setbuf(1000000);
128 _sysctl_nowrap(false);
129 _sysctl_setup();
130
131 pretest_setup();
132
133 dt_stat_time_t s = dt_stat_time_create("%s", test_name);
134
135 test(s);
136
137 dt_stat_finalize(s);
138 }
139
140 //
141 // Begin tests...
142 //
143
144 T_DECL(kdebug_trace_baseline_syscall,
145 "Test the latency of a syscall while kernel tracing is disabled") {
146 test("kdebug_trace_baseline_syscall", ^{ enable_tracing(false); }, loop_getppid);
147 }
148
149 T_DECL(kdebug_trace_kdbg_disabled,
150 "Test the latency of kdebug_trace while kernel tracing is disabled") {
151 test("kdebug_trace_kdbg_disabled", ^{ enable_tracing(false); }, loop_kdebug_trace);
152 }
153
154 T_DECL(kdebug_trace_kdbg_enabled,
155 "Test the latency of kdebug_trace while kernel tracing is enabled with no typefilter") {
156 test("kdebug_trace_kdbg_enabled", ^{ enable_tracing(true); }, loop_kdebug_trace);
157 }
158
159 T_DECL(kdebug_trace_kdbg_enabled_typefilter_pass,
160 "Test the latency of kdebug_trace while kernel tracing is enabled with a typefilter that passes the event") {
161 test("kdebug_trace_kdbg_enabled_typefilter_pass", ^{ enable_tracing(true); enable_typefilter_all_pass(); }, loop_kdebug_trace);
162 }
163
164 T_DECL(kdebug_trace_kdbg_enabled_typefilter_reject,
165 "Test the latency of kdebug_trace while kernel tracing is enabled with a typefilter that rejects the event") {
166 test("kdebug_trace_kdbg_enabled_typefilter_reject", ^{ enable_tracing(true); enable_typefilter_all_reject(); }, loop_kdebug_trace);
167 }