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.h386
1 files changed, 274 insertions, 112 deletions
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index cc0d9667e182..73523151a731 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
@@ -315,23 +428,26 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
315#undef __string 428#undef __string
316#define __string(item, src) __dynamic_array(char, item, -1) 429#define __string(item, src) __dynamic_array(char, item, -1)
317 430
318#undef TRACE_EVENT 431#undef DECLARE_EVENT_CLASS
319#define TRACE_EVENT(call, proto, args, tstruct, func, print) \ 432#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \
320static int \ 433static int \
321ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ 434ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
322{ \ 435{ \
323 struct ftrace_raw_##call field; \ 436 struct ftrace_raw_##call field; \
324 int ret; \ 437 int ret; \
325 \ 438 \
326 ret = trace_define_common_fields(event_call); \
327 if (ret) \
328 return ret; \
329 \
330 tstruct; \ 439 tstruct; \
331 \ 440 \
332 return ret; \ 441 return ret; \
333} 442}
334 443
444#undef DEFINE_EVENT
445#define DEFINE_EVENT(template, name, proto, args)
446
447#undef DEFINE_EVENT_PRINT
448#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
449 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
450
335#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 451#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
336 452
337/* 453/*
@@ -358,10 +474,10 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
358 __data_size += (len) * sizeof(type); 474 __data_size += (len) * sizeof(type);
359 475
360#undef __string 476#undef __string
361#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1) \ 477#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1)
362 478
363#undef TRACE_EVENT 479#undef DECLARE_EVENT_CLASS
364#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 480#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
365static inline int ftrace_get_offsets_##call( \ 481static inline int ftrace_get_offsets_##call( \
366 struct ftrace_data_offsets_##call *__data_offsets, proto) \ 482 struct ftrace_data_offsets_##call *__data_offsets, proto) \
367{ \ 483{ \
@@ -373,6 +489,13 @@ static inline int ftrace_get_offsets_##call( \
373 return __data_size; \ 489 return __data_size; \
374} 490}
375 491
492#undef DEFINE_EVENT
493#define DEFINE_EVENT(template, name, proto, args)
494
495#undef DEFINE_EVENT_PRINT
496#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
497 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
498
376#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 499#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
377 500
378#ifdef CONFIG_EVENT_PROFILE 501#ifdef CONFIG_EVENT_PROFILE
@@ -394,21 +517,28 @@ static inline int ftrace_get_offsets_##call( \
394 * 517 *
395 */ 518 */
396 519
397#undef TRACE_EVENT 520#undef DECLARE_EVENT_CLASS
398#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 521#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)
522
523#undef DEFINE_EVENT
524#define DEFINE_EVENT(template, name, proto, args) \
399 \ 525 \
400static void ftrace_profile_##call(proto); \ 526static void ftrace_profile_##name(proto); \
401 \ 527 \
402static int ftrace_profile_enable_##call(void) \ 528static int ftrace_profile_enable_##name(struct ftrace_event_call *unused)\
403{ \ 529{ \
404 return register_trace_##call(ftrace_profile_##call); \ 530 return register_trace_##name(ftrace_profile_##name); \
405} \ 531} \
406 \ 532 \
407static void ftrace_profile_disable_##call(void) \ 533static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\
408{ \ 534{ \
409 unregister_trace_##call(ftrace_profile_##call); \ 535 unregister_trace_##name(ftrace_profile_##name); \
410} 536}
411 537
538#undef DEFINE_EVENT_PRINT
539#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
540 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
541
412#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 542#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
413 543
414#endif 544#endif
@@ -423,18 +553,12 @@ static void ftrace_profile_disable_##call(void) \
423 * event_trace_printk(_RET_IP_, "<call>: " <fmt>); 553 * event_trace_printk(_RET_IP_, "<call>: " <fmt>);
424 * } 554 * }
425 * 555 *
426 * static int ftrace_reg_event_<call>(void) 556 * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused)
427 * { 557 * {
428 * int ret; 558 * 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 * } 559 * }
436 * 560 *
437 * static void ftrace_unreg_event_<call>(void) 561 * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
438 * { 562 * {
439 * unregister_trace_<call>(ftrace_event_<call>); 563 * unregister_trace_<call>(ftrace_event_<call>);
440 * } 564 * }
@@ -469,7 +593,7 @@ static void ftrace_profile_disable_##call(void) \
469 * trace_current_buffer_unlock_commit(buffer, event, irq_flags, pc); 593 * trace_current_buffer_unlock_commit(buffer, event, irq_flags, pc);
470 * } 594 * }
471 * 595 *
472 * static int ftrace_raw_reg_event_<call>(void) 596 * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused)
473 * { 597 * {
474 * int ret; 598 * int ret;
475 * 599 *
@@ -480,7 +604,7 @@ static void ftrace_profile_disable_##call(void) \
480 * return ret; 604 * return ret;
481 * } 605 * }
482 * 606 *
483 * static void ftrace_unreg_event_<call>(void) 607 * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
484 * { 608 * {
485 * unregister_trace_<call>(ftrace_raw_event_<call>); 609 * unregister_trace_<call>(ftrace_raw_event_<call>);
486 * } 610 * }
@@ -489,23 +613,12 @@ static void ftrace_profile_disable_##call(void) \
489 * .trace = ftrace_raw_output_<call>, <-- stage 2 613 * .trace = ftrace_raw_output_<call>, <-- stage 2
490 * }; 614 * };
491 * 615 *
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 616 * static struct ftrace_event_call __used
504 * __attribute__((__aligned__(4))) 617 * __attribute__((__aligned__(4)))
505 * __attribute__((section("_ftrace_events"))) event_<call> = { 618 * __attribute__((section("_ftrace_events"))) event_<call> = {
506 * .name = "<call>", 619 * .name = "<call>",
507 * .system = "<system>", 620 * .system = "<system>",
508 * .raw_init = ftrace_raw_init_event_<call>, 621 * .raw_init = trace_event_raw_init,
509 * .regfunc = ftrace_reg_event_<call>, 622 * .regfunc = ftrace_reg_event_<call>,
510 * .unregfunc = ftrace_unreg_event_<call>, 623 * .unregfunc = ftrace_unreg_event_<call>,
511 * .show_format = ftrace_format_<call>, 624 * .show_format = ftrace_format_<call>,
@@ -513,13 +626,9 @@ static void ftrace_profile_disable_##call(void) \
513 * 626 *
514 */ 627 */
515 628
516#undef TP_FMT
517#define TP_FMT(fmt, args...) fmt "\n", ##args
518
519#ifdef CONFIG_EVENT_PROFILE 629#ifdef CONFIG_EVENT_PROFILE
520 630
521#define _TRACE_PROFILE_INIT(call) \ 631#define _TRACE_PROFILE_INIT(call) \
522 .profile_count = ATOMIC_INIT(-1), \
523 .profile_enable = ftrace_profile_enable_##call, \ 632 .profile_enable = ftrace_profile_enable_##call, \
524 .profile_disable = ftrace_profile_disable_##call, 633 .profile_disable = ftrace_profile_disable_##call,
525 634
@@ -547,15 +656,13 @@ static void ftrace_profile_disable_##call(void) \
547#define __assign_str(dst, src) \ 656#define __assign_str(dst, src) \
548 strcpy(__get_str(dst), src); 657 strcpy(__get_str(dst), src);
549 658
550#undef TRACE_EVENT 659#undef DECLARE_EVENT_CLASS
551#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 660#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
552 \ 661 \
553static struct ftrace_event_call event_##call; \ 662static void ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \
554 \ 663 proto) \
555static void ftrace_raw_event_##call(proto) \
556{ \ 664{ \
557 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ 665 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
558 struct ftrace_event_call *event_call = &event_##call; \
559 struct ring_buffer_event *event; \ 666 struct ring_buffer_event *event; \
560 struct ftrace_raw_##call *entry; \ 667 struct ftrace_raw_##call *entry; \
561 struct ring_buffer *buffer; \ 668 struct ring_buffer *buffer; \
@@ -569,7 +676,7 @@ static void ftrace_raw_event_##call(proto) \
569 __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ 676 __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
570 \ 677 \
571 event = trace_current_buffer_lock_reserve(&buffer, \ 678 event = trace_current_buffer_lock_reserve(&buffer, \
572 event_##call.id, \ 679 event_call->id, \
573 sizeof(*entry) + __data_size, \ 680 sizeof(*entry) + __data_size, \
574 irq_flags, pc); \ 681 irq_flags, pc); \
575 if (!event) \ 682 if (!event) \
@@ -584,39 +691,58 @@ static void ftrace_raw_event_##call(proto) \
584 if (!filter_current_check_discard(buffer, event_call, entry, event)) \ 691 if (!filter_current_check_discard(buffer, event_call, entry, event)) \
585 trace_nowake_buffer_unlock_commit(buffer, \ 692 trace_nowake_buffer_unlock_commit(buffer, \
586 event, irq_flags, pc); \ 693 event, irq_flags, pc); \
587} \ 694}
695
696#undef DEFINE_EVENT
697#define DEFINE_EVENT(template, call, proto, args) \
588 \ 698 \
589static int ftrace_raw_reg_event_##call(void *ptr) \ 699static void ftrace_raw_event_##call(proto) \
590{ \ 700{ \
591 int ret; \ 701 ftrace_raw_event_id_##template(&event_##call, args); \
702} \
592 \ 703 \
593 ret = register_trace_##call(ftrace_raw_event_##call); \ 704static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\
594 if (ret) \ 705{ \
595 pr_info("event trace: Could not activate trace point " \ 706 return register_trace_##call(ftrace_raw_event_##call); \
596 "probe to " #call "\n"); \
597 return ret; \
598} \ 707} \
599 \ 708 \
600static void ftrace_raw_unreg_event_##call(void *ptr) \ 709static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\
601{ \ 710{ \
602 unregister_trace_##call(ftrace_raw_event_##call); \ 711 unregister_trace_##call(ftrace_raw_event_##call); \
603} \ 712} \
604 \ 713 \
605static struct trace_event ftrace_event_type_##call = { \ 714static struct trace_event ftrace_event_type_##call = { \
606 .trace = ftrace_raw_output_##call, \ 715 .trace = ftrace_raw_output_##call, \
607}; \ 716};
717
718#undef DEFINE_EVENT_PRINT
719#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
720 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
721
722#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
723
724#undef DECLARE_EVENT_CLASS
725#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)
726
727#undef DEFINE_EVENT
728#define DEFINE_EVENT(template, call, proto, args) \
608 \ 729 \
609static int ftrace_raw_init_event_##call(void) \ 730static struct ftrace_event_call __used \
610{ \ 731__attribute__((__aligned__(4))) \
611 int id; \ 732__attribute__((section("_ftrace_events"))) event_##call = { \
612 \ 733 .name = #call, \
613 id = register_ftrace_event(&ftrace_event_type_##call); \ 734 .system = __stringify(TRACE_SYSTEM), \
614 if (!id) \ 735 .event = &ftrace_event_type_##call, \
615 return -ENODEV; \ 736 .raw_init = trace_event_raw_init, \
616 event_##call.id = id; \ 737 .regfunc = ftrace_raw_reg_event_##call, \
617 INIT_LIST_HEAD(&event_##call.fields); \ 738 .unregfunc = ftrace_raw_unreg_event_##call, \
618 return 0; \ 739 .show_format = ftrace_format_##template, \
619} \ 740 .define_fields = ftrace_define_fields_##template, \
741 _TRACE_PROFILE_INIT(call) \
742}
743
744#undef DEFINE_EVENT_PRINT
745#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \
620 \ 746 \
621static struct ftrace_event_call __used \ 747static struct ftrace_event_call __used \
622__attribute__((__aligned__(4))) \ 748__attribute__((__aligned__(4))) \
@@ -624,11 +750,11 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
624 .name = #call, \ 750 .name = #call, \
625 .system = __stringify(TRACE_SYSTEM), \ 751 .system = __stringify(TRACE_SYSTEM), \
626 .event = &ftrace_event_type_##call, \ 752 .event = &ftrace_event_type_##call, \
627 .raw_init = ftrace_raw_init_event_##call, \ 753 .raw_init = trace_event_raw_init, \
628 .regfunc = ftrace_raw_reg_event_##call, \ 754 .regfunc = ftrace_raw_reg_event_##call, \
629 .unregfunc = ftrace_raw_unreg_event_##call, \ 755 .unregfunc = ftrace_raw_unreg_event_##call, \
630 .show_format = ftrace_format_##call, \ 756 .show_format = ftrace_format_##call, \
631 .define_fields = ftrace_define_fields_##call, \ 757 .define_fields = ftrace_define_fields_##template, \
632 _TRACE_PROFILE_INIT(call) \ 758 _TRACE_PROFILE_INIT(call) \
633} 759}
634 760
@@ -646,6 +772,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
646 * struct ftrace_event_call *event_call = &event_<call>; 772 * struct ftrace_event_call *event_call = &event_<call>;
647 * extern void perf_tp_event(int, u64, u64, void *, int); 773 * extern void perf_tp_event(int, u64, u64, void *, int);
648 * struct ftrace_raw_##call *entry; 774 * struct ftrace_raw_##call *entry;
775 * struct perf_trace_buf *trace_buf;
649 * u64 __addr = 0, __count = 1; 776 * u64 __addr = 0, __count = 1;
650 * unsigned long irq_flags; 777 * unsigned long irq_flags;
651 * struct trace_entry *ent; 778 * struct trace_entry *ent;
@@ -670,14 +797,25 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
670 * __cpu = smp_processor_id(); 797 * __cpu = smp_processor_id();
671 * 798 *
672 * if (in_nmi()) 799 * if (in_nmi())
673 * raw_data = rcu_dereference(trace_profile_buf_nmi); 800 * trace_buf = rcu_dereference(perf_trace_buf_nmi);
674 * else 801 * else
675 * raw_data = rcu_dereference(trace_profile_buf); 802 * trace_buf = rcu_dereference(perf_trace_buf);
676 * 803 *
677 * if (!raw_data) 804 * if (!trace_buf)
678 * goto end; 805 * goto end;
679 * 806 *
680 * raw_data = per_cpu_ptr(raw_data, __cpu); 807 * trace_buf = per_cpu_ptr(trace_buf, __cpu);
808 *
809 * // Avoid recursion from perf that could mess up the buffer
810 * if (trace_buf->recursion++)
811 * goto end_recursion;
812 *
813 * raw_data = trace_buf->buf;
814 *
815 * // Make recursion update visible before entering perf_tp_event
816 * // so that we protect from perf recursions.
817 *
818 * barrier();
681 * 819 *
682 * //zero dead bytes from alignment to avoid stack leak to userspace: 820 * //zero dead bytes from alignment to avoid stack leak to userspace:
683 * *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; 821 * *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;
@@ -704,21 +842,26 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
704#undef __perf_count 842#undef __perf_count
705#define __perf_count(c) __count = (c) 843#define __perf_count(c) __count = (c)
706 844
707#undef TRACE_EVENT 845#undef DECLARE_EVENT_CLASS
708#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 846#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
709static void ftrace_profile_##call(proto) \ 847static void \
848ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \
849 proto) \
710{ \ 850{ \
711 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ 851 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
712 struct ftrace_event_call *event_call = &event_##call; \ 852 extern int perf_swevent_get_recursion_context(void); \
713 extern void perf_tp_event(int, u64, u64, void *, int); \ 853 extern void perf_swevent_put_recursion_context(int rctx); \
854 extern void perf_tp_event(int, u64, u64, void *, int); \
714 struct ftrace_raw_##call *entry; \ 855 struct ftrace_raw_##call *entry; \
715 u64 __addr = 0, __count = 1; \ 856 u64 __addr = 0, __count = 1; \
716 unsigned long irq_flags; \ 857 unsigned long irq_flags; \
717 struct trace_entry *ent; \ 858 struct trace_entry *ent; \
718 int __entry_size; \ 859 int __entry_size; \
719 int __data_size; \ 860 int __data_size; \
861 char *trace_buf; \
720 char *raw_data; \ 862 char *raw_data; \
721 int __cpu; \ 863 int __cpu; \
864 int rctx; \
722 int pc; \ 865 int pc; \
723 \ 866 \
724 pc = preempt_count(); \ 867 pc = preempt_count(); \
@@ -733,17 +876,22 @@ static void ftrace_profile_##call(proto) \
733 return; \ 876 return; \
734 \ 877 \
735 local_irq_save(irq_flags); \ 878 local_irq_save(irq_flags); \
879 \
880 rctx = perf_swevent_get_recursion_context(); \
881 if (rctx < 0) \
882 goto end_recursion; \
883 \
736 __cpu = smp_processor_id(); \ 884 __cpu = smp_processor_id(); \
737 \ 885 \
738 if (in_nmi()) \ 886 if (in_nmi()) \
739 raw_data = rcu_dereference(trace_profile_buf_nmi); \ 887 trace_buf = rcu_dereference(perf_trace_buf_nmi); \
740 else \ 888 else \
741 raw_data = rcu_dereference(trace_profile_buf); \ 889 trace_buf = rcu_dereference(perf_trace_buf); \
742 \ 890 \
743 if (!raw_data) \ 891 if (!trace_buf) \
744 goto end; \ 892 goto end; \
745 \ 893 \
746 raw_data = per_cpu_ptr(raw_data, __cpu); \ 894 raw_data = per_cpu_ptr(trace_buf, __cpu); \
747 \ 895 \
748 *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; \ 896 *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; \
749 entry = (struct ftrace_raw_##call *)raw_data; \ 897 entry = (struct ftrace_raw_##call *)raw_data; \
@@ -759,10 +907,24 @@ static void ftrace_profile_##call(proto) \
759 __entry_size); \ 907 __entry_size); \
760 \ 908 \
761end: \ 909end: \
910 perf_swevent_put_recursion_context(rctx); \
911end_recursion: \
762 local_irq_restore(irq_flags); \ 912 local_irq_restore(irq_flags); \
763 \
764} 913}
765 914
915#undef DEFINE_EVENT
916#define DEFINE_EVENT(template, call, proto, args) \
917static void ftrace_profile_##call(proto) \
918{ \
919 struct ftrace_event_call *event_call = &event_##call; \
920 \
921 ftrace_profile_templ_##template(event_call, args); \
922}
923
924#undef DEFINE_EVENT_PRINT
925#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
926 DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
927
766#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 928#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
767#endif /* CONFIG_EVENT_PROFILE */ 929#endif /* CONFIG_EVENT_PROFILE */
768 930