1 /* 2 * Stage 4 of the trace events. 3 * 4 * Override the macros in <trace/trace_events.h> to include the following: 5 * 6 * For those macros defined with TRACE_EVENT: 7 * 8 * static struct trace_event_call event_<call>; 9 * 10 * static void trace_event_raw_event_<call>(void *__data, proto) 11 * { 12 * struct trace_event_file *trace_file = __data; 13 * struct trace_event_call *event_call = trace_file->event_call; 14 * struct trace_event_data_offsets_<call> __maybe_unused __data_offsets; 15 * unsigned long eflags = trace_file->flags; 16 * enum event_trigger_type __tt = ETT_NONE; 17 * struct ring_buffer_event *event; 18 * struct trace_event_raw_<call> *entry; <-- defined in stage 1 19 * struct ring_buffer *buffer; 20 * unsigned long irq_flags; 21 * int __data_size; 22 * int pc; 23 * 24 * if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) { 25 * if (eflags & EVENT_FILE_FL_TRIGGER_MODE) 26 * event_triggers_call(trace_file, NULL); 27 * if (eflags & EVENT_FILE_FL_SOFT_DISABLED) 28 * return; 29 * } 30 * 31 * local_save_flags(irq_flags); 32 * pc = preempt_count(); 33 * 34 * __data_size = trace_event_get_offsets_<call>(&__data_offsets, args); 35 * 36 * event = trace_event_buffer_lock_reserve(&buffer, trace_file, 37 * event_<call>->event.type, 38 * sizeof(*entry) + __data_size, 39 * irq_flags, pc); 40 * if (!event) 41 * return; 42 * entry = ring_buffer_event_data(event); 43 * 44 * { <assign>; } <-- Here we assign the entries by the __field and 45 * __array macros. 46 * 47 * if (eflags & EVENT_FILE_FL_TRIGGER_COND) 48 * __tt = event_triggers_call(trace_file, entry); 49 * 50 * if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, 51 * &trace_file->flags)) 52 * ring_buffer_discard_commit(buffer, event); 53 * else if (!filter_check_discard(trace_file, entry, buffer, event)) 54 * trace_buffer_unlock_commit(buffer, event, irq_flags, pc); 55 * 56 * if (__tt) 57 * event_triggers_post_call(trace_file, __tt); 58 * } 59 * 60 * static struct trace_event ftrace_event_type_<call> = { 61 * .trace = trace_raw_output_<call>, <-- stage 2 62 * }; 63 * 64 * static char print_fmt_<call>[] = <TP_printk>; 65 * 66 * static struct trace_event_class __used event_class_<template> = { 67 * .system = "<system>", 68 * .define_fields = trace_event_define_fields_<call>, 69 * .fields = LIST_HEAD_INIT(event_class_##call.fields), 70 * .raw_init = trace_event_raw_init, 71 * .probe = trace_event_raw_event_##call, 72 * .reg = trace_event_reg, 73 * }; 74 * 75 * static struct trace_event_call event_<call> = { 76 * .class = event_class_<template>, 77 * { 78 * .tp = &__tracepoint_<call>, 79 * }, 80 * .event = &ftrace_event_type_<call>, 81 * .print_fmt = print_fmt_<call>, 82 * .flags = TRACE_EVENT_FL_TRACEPOINT, 83 * }; 84 * // its only safe to use pointers when doing linker tricks to 85 * // create an array. 86 * static struct trace_event_call __used 87 * __attribute__((section("_ftrace_events"))) *__event_<call> = &event_<call>; 88 * 89 */ 90 91 #ifdef CONFIG_PERF_EVENTS 92 93 #define _TRACE_PERF_PROTO(call, proto) \ 94 static notrace void \ 95 perf_trace_##call(void *__data, proto); 96 97 #define _TRACE_PERF_INIT(call) \ 98 .perf_probe = perf_trace_##call, 99 100 #else 101 #define _TRACE_PERF_PROTO(call, proto) 102 #define _TRACE_PERF_INIT(call) 103 #endif /* CONFIG_PERF_EVENTS */ 104 105 #undef __entry 106 #define __entry entry 107 108 #undef __field 109 #define __field(type, item) 110 111 #undef __field_struct 112 #define __field_struct(type, item) 113 114 #undef __array 115 #define __array(type, item, len) 116 117 #undef __dynamic_array 118 #define __dynamic_array(type, item, len) \ 119 __entry->__data_loc_##item = __data_offsets.item; 120 121 #undef __string 122 #define __string(item, src) __dynamic_array(char, item, -1) 123 124 #undef __assign_str 125 #define __assign_str(dst, src) \ 126 strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)"); 127 128 #undef __bitmask 129 #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) 130 131 #undef __get_bitmask 132 #define __get_bitmask(field) (char *)__get_dynamic_array(field) 133 134 #undef __assign_bitmask 135 #define __assign_bitmask(dst, src, nr_bits) \ 136 memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits)) 137 138 #undef TP_fast_assign 139 #define TP_fast_assign(args...) args 140 141 #undef __perf_addr 142 #define __perf_addr(a) (a) 143 144 #undef __perf_count 145 #define __perf_count(c) (c) 146 147 #undef __perf_task 148 #define __perf_task(t) (t) 149 150 #undef DECLARE_EVENT_CLASS 151 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 152 \ 153 static notrace void \ 154 trace_event_raw_event_##call(void *__data, proto) \ 155 { \ 156 struct trace_event_file *trace_file = __data; \ 157 struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\ 158 struct trace_event_buffer fbuffer; \ 159 struct trace_event_raw_##call *entry; \ 160 int __data_size; \ 161 \ 162 if (trace_trigger_soft_disabled(trace_file)) \ 163 return; \ 164 \ 165 __data_size = trace_event_get_offsets_##call(&__data_offsets, args); \ 166 \ 167 entry = trace_event_buffer_reserve(&fbuffer, trace_file, \ 168 sizeof(*entry) + __data_size); \ 169 \ 170 if (!entry) \ 171 return; \ 172 \ 173 tstruct \ 174 \ 175 { assign; } \ 176 \ 177 trace_event_buffer_commit(&fbuffer); \ 178 } 179 /* 180 * The ftrace_test_probe is compiled out, it is only here as a build time check 181 * to make sure that if the tracepoint handling changes, the ftrace probe will 182 * fail to compile unless it too is updated. 183 */ 184 185 #undef DEFINE_EVENT 186 #define DEFINE_EVENT(template, call, proto, args) \ 187 static inline void ftrace_test_probe_##call(void) \ 188 { \ 189 check_trace_callback_type_##call(trace_event_raw_event_##template); \ 190 } 191 192 #undef DEFINE_EVENT_PRINT 193 #define DEFINE_EVENT_PRINT(template, name, proto, args, print) 194 195 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 196 197 #undef __entry 198 #define __entry REC 199 200 #undef __print_flags 201 #undef __print_symbolic 202 #undef __print_hex 203 #undef __get_dynamic_array 204 #undef __get_dynamic_array_len 205 #undef __get_str 206 #undef __get_bitmask 207 #undef __print_array 208 209 #undef TP_printk 210 #define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args) 211 212 #undef DECLARE_EVENT_CLASS 213 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 214 _TRACE_PERF_PROTO(call, PARAMS(proto)); \ 215 static char print_fmt_##call[] = print; \ 216 static struct trace_event_class __used __refdata event_class_##call = { \ 217 .system = TRACE_SYSTEM_STRING, \ 218 .define_fields = trace_event_define_fields_##call, \ 219 .fields = LIST_HEAD_INIT(event_class_##call.fields),\ 220 .raw_init = trace_event_raw_init, \ 221 .probe = trace_event_raw_event_##call, \ 222 .reg = trace_event_reg, \ 223 _TRACE_PERF_INIT(call) \ 224 }; 225 226 #undef DEFINE_EVENT 227 #define DEFINE_EVENT(template, call, proto, args) \ 228 \ 229 static struct trace_event_call __used event_##call = { \ 230 .class = &event_class_##template, \ 231 { \ 232 .tp = &__tracepoint_##call, \ 233 }, \ 234 .event.funcs = &trace_event_type_funcs_##template, \ 235 .print_fmt = print_fmt_##template, \ 236 .flags = TRACE_EVENT_FL_TRACEPOINT, \ 237 }; \ 238 static struct trace_event_call __used \ 239 __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call 240 241 #undef DEFINE_EVENT_PRINT 242 #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ 243 \ 244 static char print_fmt_##call[] = print; \ 245 \ 246 static struct trace_event_call __used event_##call = { \ 247 .class = &event_class_##template, \ 248 { \ 249 .tp = &__tracepoint_##call, \ 250 }, \ 251 .event.funcs = &trace_event_type_funcs_##call, \ 252 .print_fmt = print_fmt_##call, \ 253 .flags = TRACE_EVENT_FL_TRACEPOINT, \ 254 }; \ 255 static struct trace_event_call __used \ 256 __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call 257 258 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 259 260 #undef TRACE_SYSTEM_VAR 261 262 #ifdef CONFIG_PERF_EVENTS 263 264 #undef __entry 265 #define __entry entry 266 267 #undef __get_dynamic_array 268 #define __get_dynamic_array(field) \ 269 ((void *)__entry + (__entry->__data_loc_##field & 0xffff)) 270 271 #undef __get_dynamic_array_len 272 #define __get_dynamic_array_len(field) \ 273 ((__entry->__data_loc_##field >> 16) & 0xffff) 274 275 #undef __get_str 276 #define __get_str(field) (char *)__get_dynamic_array(field) 277 278 #undef __get_bitmask 279 #define __get_bitmask(field) (char *)__get_dynamic_array(field) 280 281 #undef __perf_addr 282 #define __perf_addr(a) (__addr = (a)) 283 284 #undef __perf_count 285 #define __perf_count(c) (__count = (c)) 286 287 #undef __perf_task 288 #define __perf_task(t) (__task = (t)) 289 290 #undef DECLARE_EVENT_CLASS 291 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 292 static notrace void \ 293 perf_trace_##call(void *__data, proto) \ 294 { \ 295 struct trace_event_call *event_call = __data; \ 296 struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\ 297 struct trace_event_raw_##call *entry; \ 298 struct pt_regs *__regs; \ 299 u64 __addr = 0, __count = 1; \ 300 struct task_struct *__task = NULL; \ 301 struct hlist_head *head; \ 302 int __entry_size; \ 303 int __data_size; \ 304 int rctx; \ 305 \ 306 __data_size = trace_event_get_offsets_##call(&__data_offsets, args); \ 307 \ 308 head = this_cpu_ptr(event_call->perf_events); \ 309 if (__builtin_constant_p(!__task) && !__task && \ 310 hlist_empty(head)) \ 311 return; \ 312 \ 313 __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ 314 sizeof(u64)); \ 315 __entry_size -= sizeof(u32); \ 316 \ 317 entry = perf_trace_buf_prepare(__entry_size, \ 318 event_call->event.type, &__regs, &rctx); \ 319 if (!entry) \ 320 return; \ 321 \ 322 perf_fetch_caller_regs(__regs); \ 323 \ 324 tstruct \ 325 \ 326 { assign; } \ 327 \ 328 perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ 329 __count, __regs, head, __task); \ 330 } 331 332 /* 333 * This part is compiled out, it is only here as a build time check 334 * to make sure that if the tracepoint handling changes, the 335 * perf probe will fail to compile unless it too is updated. 336 */ 337 #undef DEFINE_EVENT 338 #define DEFINE_EVENT(template, call, proto, args) \ 339 static inline void perf_test_probe_##call(void) \ 340 { \ 341 check_trace_callback_type_##call(perf_trace_##template); \ 342 } 343 344 345 #undef DEFINE_EVENT_PRINT 346 #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ 347 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) 348 349 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 350 #endif /* CONFIG_PERF_EVENTS */ 351