aboutsummaryrefslogtreecommitdiffstats
path: root/include/trace/ftrace.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/trace/ftrace.h')
-rw-r--r--include/trace/ftrace.h393
1 files changed, 278 insertions, 115 deletions
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index cc0d9667e182..c6fe03e902ca 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -18,6 +18,26 @@
18 18
19#include <linux/ftrace_event.h> 19#include <linux/ftrace_event.h>
20 20
21/*
22 * DECLARE_EVENT_CLASS can be used to add a generic function
23 * handlers for events. That is, if all events have the same
24 * parameters and just have distinct trace points.
25 * Each tracepoint can be defined with DEFINE_EVENT and that
26 * will map the DECLARE_EVENT_CLASS to the tracepoint.
27 *
28 * TRACE_EVENT is a one to one mapping between tracepoint and template.
29 */
30#undef TRACE_EVENT
31#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
32 DECLARE_EVENT_CLASS(name, \
33 PARAMS(proto), \
34 PARAMS(args), \
35 PARAMS(tstruct), \
36 PARAMS(assign), \
37 PARAMS(print)); \
38 DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
39
40
21#undef __field 41#undef __field
22#define __field(type, item) type item; 42#define __field(type, item) type item;
23 43
@@ -36,15 +56,21 @@
36#undef TP_STRUCT__entry 56#undef TP_STRUCT__entry
37#define TP_STRUCT__entry(args...) args 57#define TP_STRUCT__entry(args...) args
38 58
39#undef TRACE_EVENT 59#undef DECLARE_EVENT_CLASS
40#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ 60#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) \
41 struct ftrace_raw_##name { \ 61 struct ftrace_raw_##name { \
42 struct trace_entry ent; \ 62 struct trace_entry ent; \
43 tstruct \ 63 tstruct \
44 char __data[0]; \ 64 char __data[0]; \
45 }; \ 65 };
66#undef DEFINE_EVENT
67#define DEFINE_EVENT(template, name, proto, args) \
46 static struct ftrace_event_call event_##name 68 static struct ftrace_event_call event_##name
47 69
70#undef DEFINE_EVENT_PRINT
71#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
72 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
73
48#undef __cpparg 74#undef __cpparg
49#define __cpparg(arg...) arg 75#define __cpparg(arg...) arg
50 76
@@ -89,12 +115,19 @@
89#undef __string 115#undef __string
90#define __string(item, src) __dynamic_array(char, item, -1) 116#define __string(item, src) __dynamic_array(char, item, -1)
91 117
92#undef TRACE_EVENT 118#undef DECLARE_EVENT_CLASS
93#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 119#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
94 struct ftrace_data_offsets_##call { \ 120 struct ftrace_data_offsets_##call { \
95 tstruct; \ 121 tstruct; \
96 }; 122 };
97 123
124#undef DEFINE_EVENT
125#define DEFINE_EVENT(template, name, proto, args)
126
127#undef DEFINE_EVENT_PRINT
128#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
129 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
130
98#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 131#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
99 132
100/* 133/*
@@ -120,9 +153,10 @@
120#undef __field 153#undef __field
121#define __field(type, item) \ 154#define __field(type, item) \
122 ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \ 155 ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
123 "offset:%u;\tsize:%u;\n", \ 156 "offset:%u;\tsize:%u;\tsigned:%u;\n", \
124 (unsigned int)offsetof(typeof(field), item), \ 157 (unsigned int)offsetof(typeof(field), item), \
125 (unsigned int)sizeof(field.item)); \ 158 (unsigned int)sizeof(field.item), \
159 (unsigned int)is_signed_type(type)); \
126 if (!ret) \ 160 if (!ret) \
127 return 0; 161 return 0;
128 162
@@ -132,19 +166,21 @@
132#undef __array 166#undef __array
133#define __array(type, item, len) \ 167#define __array(type, item, len) \
134 ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \ 168 ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
135 "offset:%u;\tsize:%u;\n", \ 169 "offset:%u;\tsize:%u;\tsigned:%u;\n", \
136 (unsigned int)offsetof(typeof(field), item), \ 170 (unsigned int)offsetof(typeof(field), item), \
137 (unsigned int)sizeof(field.item)); \ 171 (unsigned int)sizeof(field.item), \
172 (unsigned int)is_signed_type(type)); \
138 if (!ret) \ 173 if (!ret) \
139 return 0; 174 return 0;
140 175
141#undef __dynamic_array 176#undef __dynamic_array
142#define __dynamic_array(type, item, len) \ 177#define __dynamic_array(type, item, len) \
143 ret = trace_seq_printf(s, "\tfield:__data_loc " #type "[] " #item ";\t"\ 178 ret = trace_seq_printf(s, "\tfield:__data_loc " #type "[] " #item ";\t"\
144 "offset:%u;\tsize:%u;\n", \ 179 "offset:%u;\tsize:%u;\tsigned:%u;\n", \
145 (unsigned int)offsetof(typeof(field), \ 180 (unsigned int)offsetof(typeof(field), \
146 __data_loc_##item), \ 181 __data_loc_##item), \
147 (unsigned int)sizeof(field.__data_loc_##item)); \ 182 (unsigned int)sizeof(field.__data_loc_##item), \
183 (unsigned int)is_signed_type(type)); \
148 if (!ret) \ 184 if (!ret) \
149 return 0; 185 return 0;
150 186
@@ -159,7 +195,7 @@
159#undef __get_str 195#undef __get_str
160 196
161#undef TP_printk 197#undef TP_printk
162#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args) 198#define TP_printk(fmt, args...) "\"%s\", %s\n", fmt, __stringify(args)
163 199
164#undef TP_fast_assign 200#undef TP_fast_assign
165#define TP_fast_assign(args...) args 201#define TP_fast_assign(args...) args
@@ -167,17 +203,50 @@
167#undef TP_perf_assign 203#undef TP_perf_assign
168#define TP_perf_assign(args...) 204#define TP_perf_assign(args...)
169 205
170#undef TRACE_EVENT 206#undef DECLARE_EVENT_CLASS
171#define TRACE_EVENT(call, proto, args, tstruct, func, print) \ 207#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \
172static int \ 208static int \
173ftrace_format_##call(struct ftrace_event_call *unused, \ 209ftrace_format_setup_##call(struct ftrace_event_call *unused, \
174 struct trace_seq *s) \ 210 struct trace_seq *s) \
175{ \ 211{ \
176 struct ftrace_raw_##call field __attribute__((unused)); \ 212 struct ftrace_raw_##call field __attribute__((unused)); \
177 int ret = 0; \ 213 int ret = 0; \
178 \ 214 \
179 tstruct; \ 215 tstruct; \
180 \ 216 \
217 return ret; \
218} \
219 \
220static int \
221ftrace_format_##call(struct ftrace_event_call *unused, \
222 struct trace_seq *s) \
223{ \
224 int ret = 0; \
225 \
226 ret = ftrace_format_setup_##call(unused, s); \
227 if (!ret) \
228 return ret; \
229 \
230 ret = trace_seq_printf(s, "\nprint fmt: " print); \
231 \
232 return ret; \
233}
234
235#undef DEFINE_EVENT
236#define DEFINE_EVENT(template, name, proto, args)
237
238#undef DEFINE_EVENT_PRINT
239#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
240static int \
241ftrace_format_##name(struct ftrace_event_call *unused, \
242 struct trace_seq *s) \
243{ \
244 int ret = 0; \
245 \
246 ret = ftrace_format_setup_##template(unused, s); \
247 if (!ret) \
248 return ret; \
249 \
181 trace_seq_printf(s, "\nprint fmt: " print); \ 250 trace_seq_printf(s, "\nprint fmt: " print); \
182 \ 251 \
183 return ret; \ 252 return ret; \
@@ -252,10 +321,11 @@ ftrace_format_##call(struct ftrace_event_call *unused, \
252 ftrace_print_symbols_seq(p, value, symbols); \ 321 ftrace_print_symbols_seq(p, value, symbols); \
253 }) 322 })
254 323
255#undef TRACE_EVENT 324#undef DECLARE_EVENT_CLASS
256#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 325#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
257static enum print_line_t \ 326static enum print_line_t \
258ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ 327ftrace_raw_output_id_##call(int event_id, const char *name, \
328 struct trace_iterator *iter, int flags) \
259{ \ 329{ \
260 struct trace_seq *s = &iter->seq; \ 330 struct trace_seq *s = &iter->seq; \
261 struct ftrace_raw_##call *field; \ 331 struct ftrace_raw_##call *field; \
@@ -265,6 +335,47 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
265 \ 335 \
266 entry = iter->ent; \ 336 entry = iter->ent; \
267 \ 337 \
338 if (entry->type != event_id) { \
339 WARN_ON_ONCE(1); \
340 return TRACE_TYPE_UNHANDLED; \
341 } \
342 \
343 field = (typeof(field))entry; \
344 \
345 p = &get_cpu_var(ftrace_event_seq); \
346 trace_seq_init(p); \
347 ret = trace_seq_printf(s, "%s: ", name); \
348 if (ret) \
349 ret = trace_seq_printf(s, print); \
350 put_cpu(); \
351 if (!ret) \
352 return TRACE_TYPE_PARTIAL_LINE; \
353 \
354 return TRACE_TYPE_HANDLED; \
355}
356
357#undef DEFINE_EVENT
358#define DEFINE_EVENT(template, name, proto, args) \
359static enum print_line_t \
360ftrace_raw_output_##name(struct trace_iterator *iter, int flags) \
361{ \
362 return ftrace_raw_output_id_##template(event_##name.id, \
363 #name, iter, flags); \
364}
365
366#undef DEFINE_EVENT_PRINT
367#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \
368static enum print_line_t \
369ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
370{ \
371 struct trace_seq *s = &iter->seq; \
372 struct ftrace_raw_##template *field; \
373 struct trace_entry *entry; \
374 struct trace_seq *p; \
375 int ret; \
376 \
377 entry = iter->ent; \
378 \
268 if (entry->type != event_##call.id) { \ 379 if (entry->type != event_##call.id) { \
269 WARN_ON_ONCE(1); \ 380 WARN_ON_ONCE(1); \
270 return TRACE_TYPE_UNHANDLED; \ 381 return TRACE_TYPE_UNHANDLED; \
@@ -274,14 +385,16 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
274 \ 385 \
275 p = &get_cpu_var(ftrace_event_seq); \ 386 p = &get_cpu_var(ftrace_event_seq); \
276 trace_seq_init(p); \ 387 trace_seq_init(p); \
277 ret = trace_seq_printf(s, #call ": " print); \ 388 ret = trace_seq_printf(s, "%s: ", #call); \
389 if (ret) \
390 ret = trace_seq_printf(s, print); \
278 put_cpu(); \ 391 put_cpu(); \
279 if (!ret) \ 392 if (!ret) \
280 return TRACE_TYPE_PARTIAL_LINE; \ 393 return TRACE_TYPE_PARTIAL_LINE; \
281 \ 394 \
282 return TRACE_TYPE_HANDLED; \ 395 return TRACE_TYPE_HANDLED; \
283} 396}
284 397
285#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 398#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
286 399
287#undef __field_ext 400#undef __field_ext
@@ -301,7 +414,8 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
301 BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 414 BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \
302 ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 415 ret = trace_define_field(event_call, #type "[" #len "]", #item, \
303 offsetof(typeof(field), item), \ 416 offsetof(typeof(field), item), \
304 sizeof(field.item), 0, FILTER_OTHER); \ 417 sizeof(field.item), \
418 is_signed_type(type), FILTER_OTHER); \
305 if (ret) \ 419 if (ret) \
306 return ret; 420 return ret;
307 421
@@ -309,29 +423,32 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
309#define __dynamic_array(type, item, len) \ 423#define __dynamic_array(type, item, len) \
310 ret = trace_define_field(event_call, "__data_loc " #type "[]", #item, \ 424 ret = trace_define_field(event_call, "__data_loc " #type "[]", #item, \
311 offsetof(typeof(field), __data_loc_##item), \ 425 offsetof(typeof(field), __data_loc_##item), \
312 sizeof(field.__data_loc_##item), 0, \ 426 sizeof(field.__data_loc_##item), \
313 FILTER_OTHER); 427 is_signed_type(type), FILTER_OTHER);
314 428
315#undef __string 429#undef __string
316#define __string(item, src) __dynamic_array(char, item, -1) 430#define __string(item, src) __dynamic_array(char, item, -1)
317 431
318#undef TRACE_EVENT 432#undef DECLARE_EVENT_CLASS
319#define TRACE_EVENT(call, proto, args, tstruct, func, print) \ 433#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \
320static int \ 434static int \
321ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ 435ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
322{ \ 436{ \
323 struct ftrace_raw_##call field; \ 437 struct ftrace_raw_##call field; \
324 int ret; \ 438 int ret; \
325 \ 439 \
326 ret = trace_define_common_fields(event_call); \
327 if (ret) \
328 return ret; \
329 \
330 tstruct; \ 440 tstruct; \
331 \ 441 \
332 return ret; \ 442 return ret; \
333} 443}
334 444
445#undef DEFINE_EVENT
446#define DEFINE_EVENT(template, name, proto, args)
447
448#undef DEFINE_EVENT_PRINT
449#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
450 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
451
335#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 452#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
336 453
337/* 454/*
@@ -358,10 +475,10 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
358 __data_size += (len) * sizeof(type); 475 __data_size += (len) * sizeof(type);
359 476
360#undef __string 477#undef __string
361#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1) \ 478#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1)
362 479
363#undef TRACE_EVENT 480#undef DECLARE_EVENT_CLASS
364#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 481#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
365static inline int ftrace_get_offsets_##call( \ 482static inline int ftrace_get_offsets_##call( \
366 struct ftrace_data_offsets_##call *__data_offsets, proto) \ 483 struct ftrace_data_offsets_##call *__data_offsets, proto) \
367{ \ 484{ \
@@ -373,6 +490,13 @@ static inline int ftrace_get_offsets_##call( \
373 return __data_size; \ 490 return __data_size; \
374} 491}
375 492
493#undef DEFINE_EVENT
494#define DEFINE_EVENT(template, name, proto, args)
495
496#undef DEFINE_EVENT_PRINT
497#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
498 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
499
376#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 500#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
377 501
378#ifdef CONFIG_EVENT_PROFILE 502#ifdef CONFIG_EVENT_PROFILE
@@ -394,21 +518,28 @@ static inline int ftrace_get_offsets_##call( \
394 * 518 *
395 */ 519 */
396 520
397#undef TRACE_EVENT 521#undef DECLARE_EVENT_CLASS
398#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 522#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)
523
524#undef DEFINE_EVENT
525#define DEFINE_EVENT(template, name, proto, args) \
399 \ 526 \
400static void ftrace_profile_##call(proto); \ 527static void ftrace_profile_##name(proto); \
401 \ 528 \
402static int ftrace_profile_enable_##call(void) \ 529static int ftrace_profile_enable_##name(struct ftrace_event_call *unused)\
403{ \ 530{ \
404 return register_trace_##call(ftrace_profile_##call); \ 531 return register_trace_##name(ftrace_profile_##name); \
405} \ 532} \
406 \ 533 \
407static void ftrace_profile_disable_##call(void) \ 534static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\
408{ \ 535{ \
409 unregister_trace_##call(ftrace_profile_##call); \ 536 unregister_trace_##name(ftrace_profile_##name); \
410} 537}
411 538
539#undef DEFINE_EVENT_PRINT
540#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
541 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
542
412#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 543#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
413 544
414#endif 545#endif
@@ -423,18 +554,12 @@ static void ftrace_profile_disable_##call(void) \
423 * event_trace_printk(_RET_IP_, "<call>: " <fmt>); 554 * event_trace_printk(_RET_IP_, "<call>: " <fmt>);
424 * } 555 * }
425 * 556 *
426 * static int ftrace_reg_event_<call>(void) 557 * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused)
427 * { 558 * {
428 * int ret; 559 * return register_trace_<call>(ftrace_event_<call>);
429 *
430 * ret = register_trace_<call>(ftrace_event_<call>);
431 * if (!ret)
432 * pr_info("event trace: Could not activate trace point "
433 * "probe to <call>");
434 * return ret;
435 * } 560 * }
436 * 561 *
437 * static void ftrace_unreg_event_<call>(void) 562 * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
438 * { 563 * {
439 * unregister_trace_<call>(ftrace_event_<call>); 564 * unregister_trace_<call>(ftrace_event_<call>);
440 * } 565 * }
@@ -469,7 +594,7 @@ static void ftrace_profile_disable_##call(void) \
469 * trace_current_buffer_unlock_commit(buffer, event, irq_flags, pc); 594 * trace_current_buffer_unlock_commit(buffer, event, irq_flags, pc);
470 * } 595 * }
471 * 596 *
472 * static int ftrace_raw_reg_event_<call>(void) 597 * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused)
473 * { 598 * {
474 * int ret; 599 * int ret;
475 * 600 *
@@ -480,7 +605,7 @@ static void ftrace_profile_disable_##call(void) \
480 * return ret; 605 * return ret;
481 * } 606 * }
482 * 607 *
483 * static void ftrace_unreg_event_<call>(void) 608 * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
484 * { 609 * {
485 * unregister_trace_<call>(ftrace_raw_event_<call>); 610 * unregister_trace_<call>(ftrace_raw_event_<call>);
486 * } 611 * }
@@ -489,23 +614,12 @@ static void ftrace_profile_disable_##call(void) \
489 * .trace = ftrace_raw_output_<call>, <-- stage 2 614 * .trace = ftrace_raw_output_<call>, <-- stage 2
490 * }; 615 * };
491 * 616 *
492 * static int ftrace_raw_init_event_<call>(void)
493 * {
494 * int id;
495 *
496 * id = register_ftrace_event(&ftrace_event_type_<call>);
497 * if (!id)
498 * return -ENODEV;
499 * event_<call>.id = id;
500 * return 0;
501 * }
502 *
503 * static struct ftrace_event_call __used 617 * static struct ftrace_event_call __used
504 * __attribute__((__aligned__(4))) 618 * __attribute__((__aligned__(4)))
505 * __attribute__((section("_ftrace_events"))) event_<call> = { 619 * __attribute__((section("_ftrace_events"))) event_<call> = {
506 * .name = "<call>", 620 * .name = "<call>",
507 * .system = "<system>", 621 * .system = "<system>",
508 * .raw_init = ftrace_raw_init_event_<call>, 622 * .raw_init = trace_event_raw_init,
509 * .regfunc = ftrace_reg_event_<call>, 623 * .regfunc = ftrace_reg_event_<call>,
510 * .unregfunc = ftrace_unreg_event_<call>, 624 * .unregfunc = ftrace_unreg_event_<call>,
511 * .show_format = ftrace_format_<call>, 625 * .show_format = ftrace_format_<call>,
@@ -513,13 +627,9 @@ static void ftrace_profile_disable_##call(void) \
513 * 627 *
514 */ 628 */
515 629
516#undef TP_FMT
517#define TP_FMT(fmt, args...) fmt "\n", ##args
518
519#ifdef CONFIG_EVENT_PROFILE 630#ifdef CONFIG_EVENT_PROFILE
520 631
521#define _TRACE_PROFILE_INIT(call) \ 632#define _TRACE_PROFILE_INIT(call) \
522 .profile_count = ATOMIC_INIT(-1), \
523 .profile_enable = ftrace_profile_enable_##call, \ 633 .profile_enable = ftrace_profile_enable_##call, \
524 .profile_disable = ftrace_profile_disable_##call, 634 .profile_disable = ftrace_profile_disable_##call,
525 635
@@ -547,15 +657,13 @@ static void ftrace_profile_disable_##call(void) \
547#define __assign_str(dst, src) \ 657#define __assign_str(dst, src) \
548 strcpy(__get_str(dst), src); 658 strcpy(__get_str(dst), src);
549 659
550#undef TRACE_EVENT 660#undef DECLARE_EVENT_CLASS
551#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 661#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
552 \ 662 \
553static struct ftrace_event_call event_##call; \ 663static void ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \
554 \ 664 proto) \
555static void ftrace_raw_event_##call(proto) \
556{ \ 665{ \
557 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ 666 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
558 struct ftrace_event_call *event_call = &event_##call; \
559 struct ring_buffer_event *event; \ 667 struct ring_buffer_event *event; \
560 struct ftrace_raw_##call *entry; \ 668 struct ftrace_raw_##call *entry; \
561 struct ring_buffer *buffer; \ 669 struct ring_buffer *buffer; \
@@ -569,7 +677,7 @@ static void ftrace_raw_event_##call(proto) \
569 __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ 677 __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
570 \ 678 \
571 event = trace_current_buffer_lock_reserve(&buffer, \ 679 event = trace_current_buffer_lock_reserve(&buffer, \
572 event_##call.id, \ 680 event_call->id, \
573 sizeof(*entry) + __data_size, \ 681 sizeof(*entry) + __data_size, \
574 irq_flags, pc); \ 682 irq_flags, pc); \
575 if (!event) \ 683 if (!event) \
@@ -584,39 +692,58 @@ static void ftrace_raw_event_##call(proto) \
584 if (!filter_current_check_discard(buffer, event_call, entry, event)) \ 692 if (!filter_current_check_discard(buffer, event_call, entry, event)) \
585 trace_nowake_buffer_unlock_commit(buffer, \ 693 trace_nowake_buffer_unlock_commit(buffer, \
586 event, irq_flags, pc); \ 694 event, irq_flags, pc); \
587} \ 695}
696
697#undef DEFINE_EVENT
698#define DEFINE_EVENT(template, call, proto, args) \
588 \ 699 \
589static int ftrace_raw_reg_event_##call(void *ptr) \ 700static void ftrace_raw_event_##call(proto) \
590{ \ 701{ \
591 int ret; \ 702 ftrace_raw_event_id_##template(&event_##call, args); \
703} \
592 \ 704 \
593 ret = register_trace_##call(ftrace_raw_event_##call); \ 705static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\
594 if (ret) \ 706{ \
595 pr_info("event trace: Could not activate trace point " \ 707 return register_trace_##call(ftrace_raw_event_##call); \
596 "probe to " #call "\n"); \
597 return ret; \
598} \ 708} \
599 \ 709 \
600static void ftrace_raw_unreg_event_##call(void *ptr) \ 710static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\
601{ \ 711{ \
602 unregister_trace_##call(ftrace_raw_event_##call); \ 712 unregister_trace_##call(ftrace_raw_event_##call); \
603} \ 713} \
604 \ 714 \
605static struct trace_event ftrace_event_type_##call = { \ 715static struct trace_event ftrace_event_type_##call = { \
606 .trace = ftrace_raw_output_##call, \ 716 .trace = ftrace_raw_output_##call, \
607}; \ 717};
718
719#undef DEFINE_EVENT_PRINT
720#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
721 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
722
723#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
724
725#undef DECLARE_EVENT_CLASS
726#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)
727
728#undef DEFINE_EVENT
729#define DEFINE_EVENT(template, call, proto, args) \
608 \ 730 \
609static int ftrace_raw_init_event_##call(void) \ 731static struct ftrace_event_call __used \
610{ \ 732__attribute__((__aligned__(4))) \
611 int id; \ 733__attribute__((section("_ftrace_events"))) event_##call = { \
612 \ 734 .name = #call, \
613 id = register_ftrace_event(&ftrace_event_type_##call); \ 735 .system = __stringify(TRACE_SYSTEM), \
614 if (!id) \ 736 .event = &ftrace_event_type_##call, \
615 return -ENODEV; \ 737 .raw_init = trace_event_raw_init, \
616 event_##call.id = id; \ 738 .regfunc = ftrace_raw_reg_event_##call, \
617 INIT_LIST_HEAD(&event_##call.fields); \ 739 .unregfunc = ftrace_raw_unreg_event_##call, \
618 return 0; \ 740 .show_format = ftrace_format_##template, \
619} \ 741 .define_fields = ftrace_define_fields_##template, \
742 _TRACE_PROFILE_INIT(call) \
743}
744
745#undef DEFINE_EVENT_PRINT
746#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \
620 \ 747 \
621static struct ftrace_event_call __used \ 748static struct ftrace_event_call __used \
622__attribute__((__aligned__(4))) \ 749__attribute__((__aligned__(4))) \
@@ -624,11 +751,11 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
624 .name = #call, \ 751 .name = #call, \
625 .system = __stringify(TRACE_SYSTEM), \ 752 .system = __stringify(TRACE_SYSTEM), \
626 .event = &ftrace_event_type_##call, \ 753 .event = &ftrace_event_type_##call, \
627 .raw_init = ftrace_raw_init_event_##call, \ 754 .raw_init = trace_event_raw_init, \
628 .regfunc = ftrace_raw_reg_event_##call, \ 755 .regfunc = ftrace_raw_reg_event_##call, \
629 .unregfunc = ftrace_raw_unreg_event_##call, \ 756 .unregfunc = ftrace_raw_unreg_event_##call, \
630 .show_format = ftrace_format_##call, \ 757 .show_format = ftrace_format_##call, \
631 .define_fields = ftrace_define_fields_##call, \ 758 .define_fields = ftrace_define_fields_##template, \
632 _TRACE_PROFILE_INIT(call) \ 759 _TRACE_PROFILE_INIT(call) \
633} 760}
634 761
@@ -646,6 +773,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
646 * struct ftrace_event_call *event_call = &event_<call>; 773 * struct ftrace_event_call *event_call = &event_<call>;
647 * extern void perf_tp_event(int, u64, u64, void *, int); 774 * extern void perf_tp_event(int, u64, u64, void *, int);
648 * struct ftrace_raw_##call *entry; 775 * struct ftrace_raw_##call *entry;
776 * struct perf_trace_buf *trace_buf;
649 * u64 __addr = 0, __count = 1; 777 * u64 __addr = 0, __count = 1;
650 * unsigned long irq_flags; 778 * unsigned long irq_flags;
651 * struct trace_entry *ent; 779 * struct trace_entry *ent;
@@ -670,14 +798,25 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
670 * __cpu = smp_processor_id(); 798 * __cpu = smp_processor_id();
671 * 799 *
672 * if (in_nmi()) 800 * if (in_nmi())
673 * raw_data = rcu_dereference(trace_profile_buf_nmi); 801 * trace_buf = rcu_dereference(perf_trace_buf_nmi);
674 * else 802 * else
675 * raw_data = rcu_dereference(trace_profile_buf); 803 * trace_buf = rcu_dereference(perf_trace_buf);
676 * 804 *
677 * if (!raw_data) 805 * if (!trace_buf)
678 * goto end; 806 * goto end;
679 * 807 *
680 * raw_data = per_cpu_ptr(raw_data, __cpu); 808 * trace_buf = per_cpu_ptr(trace_buf, __cpu);
809 *
810 * // Avoid recursion from perf that could mess up the buffer
811 * if (trace_buf->recursion++)
812 * goto end_recursion;
813 *
814 * raw_data = trace_buf->buf;
815 *
816 * // Make recursion update visible before entering perf_tp_event
817 * // so that we protect from perf recursions.
818 *
819 * barrier();
681 * 820 *
682 * //zero dead bytes from alignment to avoid stack leak to userspace: 821 * //zero dead bytes from alignment to avoid stack leak to userspace:
683 * *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; 822 * *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;
@@ -704,21 +843,26 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
704#undef __perf_count 843#undef __perf_count
705#define __perf_count(c) __count = (c) 844#define __perf_count(c) __count = (c)
706 845
707#undef TRACE_EVENT 846#undef DECLARE_EVENT_CLASS
708#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 847#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
709static void ftrace_profile_##call(proto) \ 848static void \
849ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \
850 proto) \
710{ \ 851{ \
711 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ 852 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
712 struct ftrace_event_call *event_call = &event_##call; \ 853 extern int perf_swevent_get_recursion_context(void); \
713 extern void perf_tp_event(int, u64, u64, void *, int); \ 854 extern void perf_swevent_put_recursion_context(int rctx); \
855 extern void perf_tp_event(int, u64, u64, void *, int); \
714 struct ftrace_raw_##call *entry; \ 856 struct ftrace_raw_##call *entry; \
715 u64 __addr = 0, __count = 1; \ 857 u64 __addr = 0, __count = 1; \
716 unsigned long irq_flags; \ 858 unsigned long irq_flags; \
717 struct trace_entry *ent; \ 859 struct trace_entry *ent; \
718 int __entry_size; \ 860 int __entry_size; \
719 int __data_size; \ 861 int __data_size; \
862 char *trace_buf; \
720 char *raw_data; \ 863 char *raw_data; \
721 int __cpu; \ 864 int __cpu; \
865 int rctx; \
722 int pc; \ 866 int pc; \
723 \ 867 \
724 pc = preempt_count(); \ 868 pc = preempt_count(); \
@@ -733,17 +877,22 @@ static void ftrace_profile_##call(proto) \
733 return; \ 877 return; \
734 \ 878 \
735 local_irq_save(irq_flags); \ 879 local_irq_save(irq_flags); \
880 \
881 rctx = perf_swevent_get_recursion_context(); \
882 if (rctx < 0) \
883 goto end_recursion; \
884 \
736 __cpu = smp_processor_id(); \ 885 __cpu = smp_processor_id(); \
737 \ 886 \
738 if (in_nmi()) \ 887 if (in_nmi()) \
739 raw_data = rcu_dereference(trace_profile_buf_nmi); \ 888 trace_buf = rcu_dereference(perf_trace_buf_nmi); \
740 else \ 889 else \
741 raw_data = rcu_dereference(trace_profile_buf); \ 890 trace_buf = rcu_dereference(perf_trace_buf); \
742 \ 891 \
743 if (!raw_data) \ 892 if (!trace_buf) \
744 goto end; \ 893 goto end; \
745 \ 894 \
746 raw_data = per_cpu_ptr(raw_data, __cpu); \ 895 raw_data = per_cpu_ptr(trace_buf, __cpu); \
747 \ 896 \
748 *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; \ 897 *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; \
749 entry = (struct ftrace_raw_##call *)raw_data; \ 898 entry = (struct ftrace_raw_##call *)raw_data; \
@@ -759,10 +908,24 @@ static void ftrace_profile_##call(proto) \
759 __entry_size); \ 908 __entry_size); \
760 \ 909 \
761end: \ 910end: \
911 perf_swevent_put_recursion_context(rctx); \
912end_recursion: \
762 local_irq_restore(irq_flags); \ 913 local_irq_restore(irq_flags); \
763 \
764} 914}
765 915
916#undef DEFINE_EVENT
917#define DEFINE_EVENT(template, call, proto, args) \
918static void ftrace_profile_##call(proto) \
919{ \
920 struct ftrace_event_call *event_call = &event_##call; \
921 \
922 ftrace_profile_templ_##template(event_call, args); \
923}
924
925#undef DEFINE_EVENT_PRINT
926#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
927 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
928
766#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 929#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
767#endif /* CONFIG_EVENT_PROFILE */ 930#endif /* CONFIG_EVENT_PROFILE */
768 931