| 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 | |
| 84 | #define PERF_CS_CODE(code) PERF_CODE(PERF_CALLSTACK, code) |
| 85 | #define PERF_CS_KSAMPLE PERF_CS_CODE(0) |
| 86 | #define PERF_CS_UPEND PERF_CS_CODE(1) |
| 87 | #define PERF_CS_USAMPLE PERF_CS_CODE(2) |
| 88 | #define PERF_CS_KDATA PERF_CS_CODE(3) |
| 89 | #define PERF_CS_UDATA PERF_CS_CODE(4) |
| 90 | #define PERF_CS_KHDR PERF_CS_CODE(5) |
| 91 | #define PERF_CS_UHDR PERF_CS_CODE(6) |
| 92 | #define PERF_CS_ERROR PERF_CS_CODE(7) |
| 93 | #define PERF_CS_BACKTRACE PERF_CS_CODE(8) |
| 94 | #define PERF_CS_LOG PERF_CS_CODE(9) |
| 95 | |
| 96 | #define PERF_TM_CODE(code) PERF_CODE(PERF_TIMER, code) |
| 97 | #define PERF_TM_FIRE PERF_TM_CODE(0) |
| 98 | #define PERF_TM_SCHED PERF_TM_CODE(1) |
| 99 | #define PERF_TM_HNDLR PERF_TM_CODE(2) |
| 100 | #define PERF_TM_PENDING PERF_TM_CODE(3) |
| 101 | #define PERF_TM_SKIPPED PERF_TM_CODE(4) |
| 102 | |
| 103 | #define PERF_PET_CODE(code) PERF_CODE(PERF_PET, code) |
| 104 | #define PERF_PET_THREAD PERF_PET_CODE(0) |
| 105 | #define PERF_PET_ERROR PERF_PET_CODE(1) |
| 106 | #define PERF_PET_RUN PERF_PET_CODE(2) |
| 107 | #define PERF_PET_PAUSE PERF_PET_CODE(3) |
| 108 | #define PERF_PET_IDLE PERF_PET_CODE(4) |
| 109 | #define PERF_PET_SAMPLE PERF_PET_CODE(5) |
| 110 | #define PERF_PET_SCHED PERF_PET_CODE(6) |
| 111 | #define PERF_PET_END PERF_PET_CODE(7) |
| 112 | #define PERF_PET_SAMPLE_TASK PERF_PET_CODE(8) |
| 113 | #define PERF_PET_SAMPLE_THREAD PERF_PET_CODE(9) |
| 114 | |
| 115 | #define PERF_AST_CODE(code) PERF_CODE(PERF_AST, code) |
| 116 | #define PERF_AST_HNDLR PERF_AST_CODE(0) |
| 117 | #define PERF_AST_ERROR PERF_AST_CODE(1) |
| 118 | |
| 119 | #define PERF_KPC_CODE(code) PERF_CODE(PERF_KPC, code) |
| 120 | #define PERF_KPC_HNDLR PERF_KPC_CODE(0) |
| 121 | #define PERF_KPC_FCOUNTER PERF_KPC_CODE(1) |
| 122 | #define PERF_KPC_COUNTER PERF_KPC_CODE(2) |
| 123 | #define PERF_KPC_DATA PERF_KPC_CODE(3) |
| 124 | #define PERF_KPC_CONFIG PERF_KPC_CODE(4) |
| 125 | #define PERF_KPC_CFG_REG PERF_KPC_CODE(5) |
| 126 | #define PERF_KPC_DATA32 PERF_KPC_CODE(6) |
| 127 | #define PERF_KPC_CFG_REG32 PERF_KPC_CODE(7) |
| 128 | #define PERF_KPC_DATA_THREAD PERF_KPC_CODE(8) |
| 129 | #define PERF_KPC_DATA_THREAD32 PERF_KPC_CODE(9) |
| 130 | #define PERF_KPC_CPU_SAMPLE PERF_KPC_CODE(10) |
| 131 | #define PERF_KPC_THREAD_SAMPLE PERF_KPC_CODE(11) |
| 132 | |
| 133 | #define PERF_KDBG_CODE(code) PERF_CODE(PERF_KDBG, code) |
| 134 | #define PERF_KDBG_HNDLR PERF_KDBG_CODE(0) |
| 135 | |
| 136 | #define PERF_TK_CODE(code) PERF_CODE(PERF_TASK, code) |
| 137 | #define PERF_TK_SNAP_SAMPLE PERF_TK_CODE(0) |
| 138 | #define PERF_TK_SNAP_DATA PERF_TK_CODE(1) |
| 139 | #define PERF_TK_SNAP_DATA1_32 PERF_TK_CODE(2) |
| 140 | #define PERF_TK_SNAP_DATA2_32 PERF_TK_CODE(3) |
| 141 | #define PERF_TK_INFO_DATA PERF_TK_CODE(4) |
| 142 | |
| 143 | #define PERF_LZ_CODE(code) PERF_CODE(PERF_LAZY, code) |
| 144 | #define PERF_LZ_MKRUNNABLE PERF_LZ_CODE(0) |
| 145 | #define PERF_LZ_WAITSAMPLE PERF_LZ_CODE(1) |
| 146 | #define PERF_LZ_CPUSAMPLE PERF_LZ_CODE(2) |
| 147 | |
| 148 | #define PERF_MI_CODE(code) PERF_CODE(PERF_MEMINFO, code) |
| 149 | #define PERF_MI_SAMPLE PERF_MI_CODE(0) |
| 150 | #define PERF_MI_DATA PERF_MI_CODE(1) |
| 151 | #define PERF_MI_SYS_DATA PERF_MI_CODE(2) |
| 152 | #define PERF_MI_SYS_DATA_2 PERF_MI_CODE(3) |
| 153 | |
| 154 | /* error sub-codes for trace data */ |
| 155 | enum |
| 156 | { |
| 157 | ERR_TASK, |
| 158 | ERR_THREAD, |
| 159 | ERR_PID, |
| 160 | ERR_FRAMES, |
| 161 | ERR_GETSTACK, |
| 162 | ERR_NOMEM, |
| 163 | }; |
| 164 | |
| 165 | /* level of kperf's logging to kdebug */ |
| 166 | #define KPERF_DEBUG_DATA 0 |
| 167 | #define KPERF_DEBUG_INFO 1 |
| 168 | #define KPERF_DEBUG_VERBOSE 2 |
| 169 | extern int kperf_debug_level; |
| 170 | |
| 171 | /* BUF_DATA tracepoints are for logging actual kperf results. */ |
| 172 | |
| 173 | #define BUF_DATA_INT(EVENTID, A0, A1, A2, A3) KERNEL_DEBUG_CONSTANT_IST(~KDEBUG_ENABLE_PPT, EVENTID, A0, A1, A2, A3, 0) |
| 174 | |
| 175 | #define BUF_DATA(EVENTID, ...) BUF_DATA_(EVENTID, ## __VA_ARGS__, 4, 3, 2, 1, 0) |
| 176 | #define BUF_DATA_(EVENTID, A1, A2, A3, A4, N_ARGS, ...) BUF_DATA##N_ARGS(EVENTID, A1, A2, A3, A4) |
| 177 | #define BUF_DATA0(EVENTID, A1, A2, A3, A4) BUF_DATA_INT(EVENTID, 0, 0, 0, 0) |
| 178 | #define BUF_DATA1(EVENTID, A1, A2, A3, A4) BUF_DATA_INT(EVENTID, A1, 0, 0, 0) |
| 179 | #define BUF_DATA2(EVENTID, A1, A2, A3, A4) BUF_DATA_INT(EVENTID, A1, A2, 0, 0) |
| 180 | #define BUF_DATA3(EVENTID, A1, A2, A3, A4) BUF_DATA_INT(EVENTID, A1, A2, A3, 0) |
| 181 | #define BUF_DATA4(EVENTID, A1, A2, A3, A4) BUF_DATA_INT(EVENTID, A1, A2, A3, A4) |
| 182 | |
| 183 | /* |
| 184 | * BUF_INFO tracepoints are for logging debugging information relevant to |
| 185 | * testing kperf's internal functions. |
| 186 | */ |
| 187 | |
| 188 | #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) |
| 189 | #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) |
| 190 | #else |
| 191 | #define BUF_INFO_INT(EVENTID, A1, A2, A3, A4) do { (void)(EVENTID); (void)(A1); (void)(A2); (void)(A3); (void)(A4); } while ((0)) |
| 192 | #endif |
| 193 | |
| 194 | #define BUF_INFO(EVENTID, ...) BUF_INFO_(EVENTID, ## __VA_ARGS__, 4, 3, 2, 1, 0) |
| 195 | #define BUF_INFO_(EVENTID, A1, A2, A3, A4, N_ARGS, ...) BUF_INFO##N_ARGS(EVENTID, A1, A2, A3, A4) |
| 196 | #define BUF_INFO0(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, 0, 0, 0, 0) |
| 197 | #define BUF_INFO1(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, A1, 0, 0, 0) |
| 198 | #define BUF_INFO2(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, A1, A2, 0, 0) |
| 199 | #define BUF_INFO3(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, A1, A2, A3, 0) |
| 200 | #define BUF_INFO4(EVENTID, A1, A2, A3, A4) BUF_INFO_INT(EVENTID, A1, A2, A3, A4) |
| 201 | |
| 202 | /* |
| 203 | * BUF_VERB tracepoints are for logging precise details of kperf's |
| 204 | * internal functions, like timing information for samplers. |
| 205 | */ |
| 206 | |
| 207 | #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) |
| 208 | #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) |
| 209 | #else |
| 210 | #define BUF_VERB_INT(EVENTID, A1, A2, A3, A4) do { (void)(EVENTID); (void)(A1); (void)(A2); (void)(A3); (void)(A4); } while ((0)) |
| 211 | #endif |
| 212 | |
| 213 | #define BUF_VERB(EVENTID, ...) BUF_VERB_(EVENTID, ## __VA_ARGS__, 4, 3, 2, 1, 0) |
| 214 | #define BUF_VERB_(EVENTID, A1, A2, A3, A4, N_ARGS, ...) BUF_VERB##N_ARGS(EVENTID, A1, A2, A3, A4) |
| 215 | #define BUF_VERB0(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, 0, 0, 0, 0) |
| 216 | #define BUF_VERB1(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, A1, 0, 0, 0) |
| 217 | #define BUF_VERB2(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, A1, A2, 0, 0) |
| 218 | #define BUF_VERB3(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, A1, A2, A3, 0) |
| 219 | #define BUF_VERB4(EVENTID, A1, A2, A3, A4) BUF_VERB_INT(EVENTID, A1, A2, A3, A4) |
| 220 | |
| 221 | |