1 | /* |
2 | * Copyright (c) 2011-2016 Apple Computer, Inc. All rights reserved. |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
5 | * |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License |
8 | * Version 2.0 (the 'License'). You may not use this file except in |
9 | * compliance with the License. The rights granted to you under the License |
10 | * may not be used to create, or enable the creation or redistribution of, |
11 | * unlawful or unlicensed copies of an Apple operating system, or to |
12 | * circumvent, violate, or enable the circumvention or violation of, any |
13 | * terms of an Apple operating system software license agreement. |
14 | * |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. |
17 | * |
18 | * The Original Code and all software distributed under the License are |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
23 | * Please see the License for the specific language governing rights and |
24 | * limitations under the License. |
25 | * |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ |
28 | |
29 | /* wrapper around kdebug */ |
30 | |
31 | #include <sys/kdebug.h> |
32 | |
33 | /* kdebug codes */ |
34 | #define PERF_CODE(SubClass, code) KDBG_CODE(DBG_PERF, SubClass, code) |
35 | |
36 | /* broad sub-classes */ |
37 | #define PERF_GENERIC (0) |
38 | #define PERF_THREADINFO (1) |
39 | #define PERF_CALLSTACK (2) |
40 | #define PERF_TIMER (3) |
41 | #define PERF_PET (4) |
42 | #define PERF_AST (5) |
43 | #define PERF_KPC (6) |
44 | #define PERF_KDBG (7) |
45 | #define PERF_TASK (8) |
46 | #define PERF_LAZY (9) |
47 | #define PERF_MEMINFO (10) |
48 | |
49 | /* helpers for 32-bit */ |
50 | #define UPPER_32(U64) ((U64) >> 32) |
51 | #define LOWER_32(U64) ((U64) & (UINT32_MAX)) |
52 | #define ENCODE_UPPER_64(U32) (((uint64_t)(U32)) << 32) |
53 | #define ENCODE_LOWER_64(U32) (((uint64_t)(U32)) & (UINT32_MAX)) |
54 | |
55 | /* sub-class codes */ |
56 | #define PERF_GEN_CODE(code) PERF_CODE(PERF_GENERIC, code) |
57 | #define PERF_GEN_EVENT PERF_GEN_CODE(0) |
58 | |
59 | #define PERF_TI_CODE(code) PERF_CODE(PERF_THREADINFO, code) |
60 | #define PERF_TI_SAMPLE PERF_TI_CODE(0) |
61 | #define PERF_TI_DATA PERF_TI_CODE(1) |
62 | #define PERF_TI_XSAMPLE PERF_TI_CODE(2) |
63 | #define PERF_TI_XPEND PERF_TI_CODE(3) |
64 | #define PERF_TI_XDATA PERF_TI_CODE(4) |
65 | #define PERF_TI_CSWITCH PERF_TI_CODE(5) |
66 | #define PERF_TI_SCHEDSAMPLE PERF_TI_CODE(6) |
67 | #define PERF_TI_SCHEDDATA PERF_TI_CODE(7) |
68 | #define PERF_TI_SNAPSAMPLE PERF_TI_CODE(8) |
69 | #define PERF_TI_SNAPDATA PERF_TI_CODE(9) |
70 | #define PERF_TI_DISPSAMPLE PERF_TI_CODE(10) |
71 | #define PERF_TI_DISPDATA PERF_TI_CODE(11) |
72 | #define PERF_TI_DISPPEND PERF_TI_CODE(12) |
73 | #define PERF_TI_SNAPDATA_32 PERF_TI_CODE(13) |
74 | #define PERF_TI_DISPDATA_32 PERF_TI_CODE(14) |
75 | #define PERF_TI_SCHEDDATA1_32 PERF_TI_CODE(15) |
76 | #define PERF_TI_SCHEDDATA2_32 PERF_TI_CODE(16) |
77 | #define PERF_TI_INSCYCDATA PERF_TI_CODE(17) |
78 | #define PERF_TI_INSCYCDATA_32 PERF_TI_CODE(18) |
79 | #define PERF_TI_SCHEDDATA_2 PERF_TI_CODE(19) |
80 | #define PERF_TI_SCHEDDATA2_32_2 PERF_TI_CODE(20) |
81 | #define PERF_TI_SCHEDDATA3_32 PERF_TI_CODE(21) |
82 | #define PERF_TI_SCHEDDATA_3 PERF_TI_CODE(22) |
83 | #define PERF_TI_DISPLABEL PERF_TI_CODE(23) |
84 | |
85 | #define PERF_CS_CODE(code) PERF_CODE(PERF_CALLSTACK, code) |
86 | #define PERF_CS_KSAMPLE PERF_CS_CODE(0) |
87 | #define PERF_CS_UPEND PERF_CS_CODE(1) |
88 | #define PERF_CS_USAMPLE PERF_CS_CODE(2) |
89 | #define PERF_CS_KDATA PERF_CS_CODE(3) |
90 | #define PERF_CS_UDATA PERF_CS_CODE(4) |
91 | #define PERF_CS_KHDR PERF_CS_CODE(5) |
92 | #define PERF_CS_UHDR PERF_CS_CODE(6) |
93 | #define PERF_CS_ERROR PERF_CS_CODE(7) |
94 | #define PERF_CS_BACKTRACE PERF_CS_CODE(8) |
95 | #define PERF_CS_LOG PERF_CS_CODE(9) |
96 | #define PERF_CS_EXHDR PERF_CS_CODE(10) |
97 | #define PERF_CS_EXDATA PERF_CS_CODE(11) |
98 | #define PERF_CS_EXSTACKHDR PERF_CS_CODE(12) |
99 | #define PERF_CS_EXSTACK PERF_CS_CODE(13) |
100 | #define PERF_CS_KEXOFFSET PERF_CS_CODE(14) |
101 | |
102 | #define PERF_TM_CODE(code) PERF_CODE(PERF_TIMER, code) |
103 | #define PERF_TM_FIRE PERF_TM_CODE(0) |
104 | #define PERF_TM_SCHED PERF_TM_CODE(1) |
105 | #define PERF_TM_HNDLR PERF_TM_CODE(2) |
106 | #define PERF_TM_PENDING PERF_TM_CODE(3) |
107 | #define PERF_TM_SKIPPED PERF_TM_CODE(4) |
108 | |
109 | #define PERF_PET_CODE(code) PERF_CODE(PERF_PET, code) |
110 | #define PERF_PET_THREAD PERF_PET_CODE(0) |
111 | #define PERF_PET_ERROR PERF_PET_CODE(1) |
112 | #define PERF_PET_RUN PERF_PET_CODE(2) |
113 | #define PERF_PET_PAUSE PERF_PET_CODE(3) |
114 | #define PERF_PET_IDLE PERF_PET_CODE(4) |
115 | #define PERF_PET_SAMPLE PERF_PET_CODE(5) |
116 | #define PERF_PET_SCHED PERF_PET_CODE(6) |
117 | #define PERF_PET_END PERF_PET_CODE(7) |
118 | #define PERF_PET_SAMPLE_TASK PERF_PET_CODE(8) |
119 | #define PERF_PET_SAMPLE_THREAD PERF_PET_CODE(9) |
120 | |
121 | #define PERF_AST_CODE(code) PERF_CODE(PERF_AST, code) |
122 | #define PERF_AST_HNDLR PERF_AST_CODE(0) |
123 | #define PERF_AST_ERROR PERF_AST_CODE(1) |
124 | #define PERF_AST_EXCLAVES PERF_AST_CODE(2) |
125 | |
126 | #define PERF_KPC_CODE(code) PERF_CODE(PERF_KPC, code) |
127 | #define PERF_KPC_HNDLR PERF_KPC_CODE(0) |
128 | #define PERF_KPC_FCOUNTER PERF_KPC_CODE(1) |
129 | #define PERF_KPC_COUNTER PERF_KPC_CODE(2) |
130 | #define PERF_KPC_DATA PERF_KPC_CODE(3) |
131 | #define PERF_KPC_CONFIG PERF_KPC_CODE(4) |
132 | #define PERF_KPC_CFG_REG PERF_KPC_CODE(5) |
133 | #define PERF_KPC_DATA32 PERF_KPC_CODE(6) |
134 | #define PERF_KPC_CFG_REG32 PERF_KPC_CODE(7) |
135 | #define PERF_KPC_DATA_THREAD PERF_KPC_CODE(8) |
136 | #define PERF_KPC_DATA_THREAD32 PERF_KPC_CODE(9) |
137 | #define PERF_KPC_CPU_SAMPLE PERF_KPC_CODE(10) |
138 | #define PERF_KPC_THREAD_SAMPLE PERF_KPC_CODE(11) |
139 | |
140 | #define PERF_KDBG_CODE(code) PERF_CODE(PERF_KDBG, code) |
141 | #define PERF_KDBG_HNDLR PERF_KDBG_CODE(0) |
142 | |
143 | #define PERF_TK_CODE(code) PERF_CODE(PERF_TASK, code) |
144 | #define PERF_TK_SNAP_SAMPLE PERF_TK_CODE(0) |
145 | #define PERF_TK_SNAP_DATA PERF_TK_CODE(1) |
146 | #define PERF_TK_SNAP_DATA1_32 PERF_TK_CODE(2) |
147 | #define PERF_TK_SNAP_DATA2_32 PERF_TK_CODE(3) |
148 | #define PERF_TK_INFO_DATA PERF_TK_CODE(4) |
149 | |
150 | #define PERF_LZ_CODE(code) PERF_CODE(PERF_LAZY, code) |
151 | #define PERF_LZ_MKRUNNABLE PERF_LZ_CODE(0) |
152 | #define PERF_LZ_WAITSAMPLE PERF_LZ_CODE(1) |
153 | #define PERF_LZ_CPUSAMPLE PERF_LZ_CODE(2) |
154 | |
155 | #define PERF_MI_CODE(code) PERF_CODE(PERF_MEMINFO, code) |
156 | #define PERF_MI_SAMPLE PERF_MI_CODE(0) |
157 | #define PERF_MI_DATA PERF_MI_CODE(1) |
158 | #define PERF_MI_SYS_DATA PERF_MI_CODE(2) |
159 | #define PERF_MI_SYS_DATA_2 PERF_MI_CODE(3) |
160 | #define PERF_MI_SYS_DATA_3 PERF_MI_CODE(4) |
161 | |
162 | /* error sub-codes for trace data */ |
163 | enum{ |
164 | ERR_TASK, |
165 | ERR_THREAD, |
166 | ERR_PID, |
167 | ERR_FRAMES, |
168 | ERR_GETSTACK, |
169 | ERR_NOMEM, |
170 | }; |
171 | |
172 | /* level of kperf's logging to kdebug */ |
173 | #define KPERF_DEBUG_DATA 0 |
174 | #define KPERF_DEBUG_INFO 1 |
175 | #define KPERF_DEBUG_VERBOSE 2 |
176 | extern int kperf_debug_level; |
177 | |
178 | /* BUF_DATA tracepoints are for logging actual kperf results. */ |
179 | |
180 | #define BUF_DATA(EVENTID, ...) KDBG_RELEASE(EVENTID, ## __VA_ARGS__) |
181 | |
182 | /* |
183 | * BUF_INFO tracepoints are for logging debugging information relevant to |
184 | * testing kperf's internal functions. |
185 | */ |
186 | |
187 | #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) |
188 | #define BUF_INFO_INT(EVENTID, A1, A2, A3, A4) if (__improbable(kperf_debug_level >= KPERF_DEBUG_INFO)) KERNEL_DEBUG_CONSTANT(EVENTID, A1, A2, A3, A4, 0) |
189 | #else |
190 | #define BUF_INFO_INT(EVENTID, A1, A2, A3, A4) do { (void)(EVENTID); (void)(A1); (void)(A2); (void)(A3); (void)(A4); } while ((0)) |
191 | #endif |
192 | |
193 | #define BUF_INFO(EVENTID, ...) BUF_INFO_(EVENTID, ## __VA_ARGS__, 4, 3, 2, 1, 0) |
194 | #define BUF_INFO_(EVENTID, A1, A2, A3, A4, N_ARGS, ...) BUF_INFO##N_ARGS(EVENTID, A1, A2, A3, A4) |
195 | #define BUF_INFO0(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, 0, 0, 0, 0) |
196 | #define BUF_INFO1(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, A1, 0, 0, 0) |
197 | #define BUF_INFO2(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, A1, A2, 0, 0) |
198 | #define BUF_INFO3(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, A1, A2, A3, 0) |
199 | #define BUF_INFO4(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, A1, A2, A3, A4) |
200 | |
201 | /* |
202 | * BUF_VERB tracepoints are for logging precise details of kperf's |
203 | * internal functions, like timing information for samplers. |
204 | */ |
205 | |
206 | #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) |
207 | #define BUF_VERB_INT(EVENTID, A1, A2, A3, A4) if (__improbable(kperf_debug_level >= KPERF_DEBUG_VERBOSE)) KERNEL_DEBUG_CONSTANT(EVENTID, A1, A2, A3, A4, 0) |
208 | #else |
209 | #define BUF_VERB_INT(EVENTID, A1, A2, A3, A4) do { (void)(EVENTID); (void)(A1); (void)(A2); (void)(A3); (void)(A4); } while ((0)) |
210 | #endif |
211 | |
212 | #define BUF_VERB(EVENTID, ...) BUF_VERB_(EVENTID, ## __VA_ARGS__, 4, 3, 2, 1, 0) |
213 | #define BUF_VERB_(EVENTID, A1, A2, A3, A4, N_ARGS, ...) BUF_VERB##N_ARGS(EVENTID, A1, A2, A3, A4) |
214 | #define BUF_VERB0(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, 0, 0, 0, 0) |
215 | #define BUF_VERB1(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, A1, 0, 0, 0) |
216 | #define BUF_VERB2(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, A1, A2, 0, 0) |
217 | #define BUF_VERB3(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, A1, A2, A3, 0) |
218 | #define BUF_VERB4(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, A1, A2, A3, A4) |
219 | |