diff options
-rw-r--r-- | include/linux/tracepoint.h | 4 | ||||
-rw-r--r-- | include/trace/define_trace.h | 6 | ||||
-rw-r--r-- | include/trace/ftrace.h | 149 |
3 files changed, 117 insertions, 42 deletions
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 2aac8a83e89b..88a5b5a809ec 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
@@ -280,6 +280,10 @@ static inline void tracepoint_synchronize_unregister(void) | |||
280 | * TRACE_EVENT_FN to perform any (un)registration work. | 280 | * TRACE_EVENT_FN to perform any (un)registration work. |
281 | */ | 281 | */ |
282 | 282 | ||
283 | #define TRACE_EVENT_TEMPLATE(name, proto, args, tstruct, assign, print) | ||
284 | #define DEFINE_EVENT(template, name, proto, args) \ | ||
285 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | ||
286 | |||
283 | #define TRACE_EVENT(name, proto, args, struct, assign, print) \ | 287 | #define TRACE_EVENT(name, proto, args, struct, assign, print) \ |
284 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | 288 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) |
285 | #define TRACE_EVENT_FN(name, proto, args, struct, \ | 289 | #define TRACE_EVENT_FN(name, proto, args, struct, \ |
diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h index 2a4b3bf74033..244985814a43 100644 --- a/include/trace/define_trace.h +++ b/include/trace/define_trace.h | |||
@@ -31,6 +31,10 @@ | |||
31 | assign, print, reg, unreg) \ | 31 | assign, print, reg, unreg) \ |
32 | DEFINE_TRACE_FN(name, reg, unreg) | 32 | DEFINE_TRACE_FN(name, reg, unreg) |
33 | 33 | ||
34 | #undef DEFINE_EVENT | ||
35 | #define DEFINE_EVENT(template, name, proto, args) \ | ||
36 | DEFINE_TRACE(name) | ||
37 | |||
34 | #undef DECLARE_TRACE | 38 | #undef DECLARE_TRACE |
35 | #define DECLARE_TRACE(name, proto, args) \ | 39 | #define DECLARE_TRACE(name, proto, args) \ |
36 | DEFINE_TRACE(name) | 40 | DEFINE_TRACE(name) |
@@ -63,6 +67,8 @@ | |||
63 | 67 | ||
64 | #undef TRACE_EVENT | 68 | #undef TRACE_EVENT |
65 | #undef TRACE_EVENT_FN | 69 | #undef TRACE_EVENT_FN |
70 | #undef TRACE_EVENT_TEMPLATE | ||
71 | #undef DEFINE_EVENT | ||
66 | #undef TRACE_HEADER_MULTI_READ | 72 | #undef TRACE_HEADER_MULTI_READ |
67 | 73 | ||
68 | /* Only undef what we defined in this file */ | 74 | /* Only undef what we defined in this file */ |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index c3417c13e3ed..2969f65d8002 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 | * TRACE_EVENT_TEMPLATE 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 TRACE_EVENT_TEMPLATE 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 | TRACE_EVENT_TEMPLATE(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,13 +56,15 @@ | |||
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 TRACE_EVENT_TEMPLATE |
40 | #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ | 60 | #define TRACE_EVENT_TEMPLATE(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 | ||
48 | #undef __cpparg | 70 | #undef __cpparg |
@@ -89,12 +111,15 @@ | |||
89 | #undef __string | 111 | #undef __string |
90 | #define __string(item, src) __dynamic_array(char, item, -1) | 112 | #define __string(item, src) __dynamic_array(char, item, -1) |
91 | 113 | ||
92 | #undef TRACE_EVENT | 114 | #undef TRACE_EVENT_TEMPLATE |
93 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ | 115 | #define TRACE_EVENT_TEMPLATE(call, proto, args, tstruct, assign, print) \ |
94 | struct ftrace_data_offsets_##call { \ | 116 | struct ftrace_data_offsets_##call { \ |
95 | tstruct; \ | 117 | tstruct; \ |
96 | }; | 118 | }; |
97 | 119 | ||
120 | #undef DEFINE_EVENT | ||
121 | #define DEFINE_EVENT(template, name, proto, args) | ||
122 | |||
98 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 123 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
99 | 124 | ||
100 | /* | 125 | /* |
@@ -170,8 +195,8 @@ | |||
170 | #undef TP_perf_assign | 195 | #undef TP_perf_assign |
171 | #define TP_perf_assign(args...) | 196 | #define TP_perf_assign(args...) |
172 | 197 | ||
173 | #undef TRACE_EVENT | 198 | #undef TRACE_EVENT_TEMPLATE |
174 | #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ | 199 | #define TRACE_EVENT_TEMPLATE(call, proto, args, tstruct, func, print) \ |
175 | static int \ | 200 | static int \ |
176 | ftrace_format_##call(struct ftrace_event_call *unused, \ | 201 | ftrace_format_##call(struct ftrace_event_call *unused, \ |
177 | struct trace_seq *s) \ | 202 | struct trace_seq *s) \ |
@@ -186,6 +211,9 @@ ftrace_format_##call(struct ftrace_event_call *unused, \ | |||
186 | return ret; \ | 211 | return ret; \ |
187 | } | 212 | } |
188 | 213 | ||
214 | #undef DEFINE_EVENT | ||
215 | #define DEFINE_EVENT(template, name, proto, args) | ||
216 | |||
189 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 217 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
190 | 218 | ||
191 | /* | 219 | /* |
@@ -255,10 +283,11 @@ ftrace_format_##call(struct ftrace_event_call *unused, \ | |||
255 | ftrace_print_symbols_seq(p, value, symbols); \ | 283 | ftrace_print_symbols_seq(p, value, symbols); \ |
256 | }) | 284 | }) |
257 | 285 | ||
258 | #undef TRACE_EVENT | 286 | #undef TRACE_EVENT_TEMPLATE |
259 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ | 287 | #define TRACE_EVENT_TEMPLATE(call, proto, args, tstruct, assign, print) \ |
260 | static enum print_line_t \ | 288 | static enum print_line_t \ |
261 | ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | 289 | ftrace_raw_output_id_##call(int event_id, const char *name, \ |
290 | struct trace_iterator *iter, int flags) \ | ||
262 | { \ | 291 | { \ |
263 | struct trace_seq *s = &iter->seq; \ | 292 | struct trace_seq *s = &iter->seq; \ |
264 | struct ftrace_raw_##call *field; \ | 293 | struct ftrace_raw_##call *field; \ |
@@ -268,7 +297,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
268 | \ | 297 | \ |
269 | entry = iter->ent; \ | 298 | entry = iter->ent; \ |
270 | \ | 299 | \ |
271 | if (entry->type != event_##call.id) { \ | 300 | if (entry->type != event_id) { \ |
272 | WARN_ON_ONCE(1); \ | 301 | WARN_ON_ONCE(1); \ |
273 | return TRACE_TYPE_UNHANDLED; \ | 302 | return TRACE_TYPE_UNHANDLED; \ |
274 | } \ | 303 | } \ |
@@ -277,14 +306,25 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
277 | \ | 306 | \ |
278 | p = &get_cpu_var(ftrace_event_seq); \ | 307 | p = &get_cpu_var(ftrace_event_seq); \ |
279 | trace_seq_init(p); \ | 308 | trace_seq_init(p); \ |
280 | ret = trace_seq_printf(s, #call ": " print); \ | 309 | ret = trace_seq_printf(s, "%s: ", name); \ |
310 | if (ret) \ | ||
311 | ret = trace_seq_printf(s, print); \ | ||
281 | put_cpu(); \ | 312 | put_cpu(); \ |
282 | if (!ret) \ | 313 | if (!ret) \ |
283 | return TRACE_TYPE_PARTIAL_LINE; \ | 314 | return TRACE_TYPE_PARTIAL_LINE; \ |
284 | \ | 315 | \ |
285 | return TRACE_TYPE_HANDLED; \ | 316 | return TRACE_TYPE_HANDLED; \ |
286 | } | 317 | } |
287 | 318 | ||
319 | #undef DEFINE_EVENT | ||
320 | #define DEFINE_EVENT(template, name, proto, args) \ | ||
321 | static enum print_line_t \ | ||
322 | ftrace_raw_output_##name(struct trace_iterator *iter, int flags) \ | ||
323 | { \ | ||
324 | return ftrace_raw_output_id_##template(event_##name.id, \ | ||
325 | #name, iter, flags); \ | ||
326 | } | ||
327 | |||
288 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 328 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
289 | 329 | ||
290 | #undef __field_ext | 330 | #undef __field_ext |
@@ -318,8 +358,8 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
318 | #undef __string | 358 | #undef __string |
319 | #define __string(item, src) __dynamic_array(char, item, -1) | 359 | #define __string(item, src) __dynamic_array(char, item, -1) |
320 | 360 | ||
321 | #undef TRACE_EVENT | 361 | #undef TRACE_EVENT_TEMPLATE |
322 | #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ | 362 | #define TRACE_EVENT_TEMPLATE(call, proto, args, tstruct, func, print) \ |
323 | static int \ | 363 | static int \ |
324 | ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ | 364 | ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ |
325 | { \ | 365 | { \ |
@@ -335,6 +375,9 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ | |||
335 | return ret; \ | 375 | return ret; \ |
336 | } | 376 | } |
337 | 377 | ||
378 | #undef DEFINE_EVENT | ||
379 | #define DEFINE_EVENT(template, name, proto, args) | ||
380 | |||
338 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 381 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
339 | 382 | ||
340 | /* | 383 | /* |
@@ -361,10 +404,10 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ | |||
361 | __data_size += (len) * sizeof(type); | 404 | __data_size += (len) * sizeof(type); |
362 | 405 | ||
363 | #undef __string | 406 | #undef __string |
364 | #define __string(item, src) __dynamic_array(char, item, strlen(src) + 1) \ | 407 | #define __string(item, src) __dynamic_array(char, item, strlen(src) + 1) |
365 | 408 | ||
366 | #undef TRACE_EVENT | 409 | #undef TRACE_EVENT_TEMPLATE |
367 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ | 410 | #define TRACE_EVENT_TEMPLATE(call, proto, args, tstruct, assign, print) \ |
368 | static inline int ftrace_get_offsets_##call( \ | 411 | static inline int ftrace_get_offsets_##call( \ |
369 | struct ftrace_data_offsets_##call *__data_offsets, proto) \ | 412 | struct ftrace_data_offsets_##call *__data_offsets, proto) \ |
370 | { \ | 413 | { \ |
@@ -376,6 +419,9 @@ static inline int ftrace_get_offsets_##call( \ | |||
376 | return __data_size; \ | 419 | return __data_size; \ |
377 | } | 420 | } |
378 | 421 | ||
422 | #undef DEFINE_EVENT | ||
423 | #define DEFINE_EVENT(template, name, proto, args) | ||
424 | |||
379 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 425 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
380 | 426 | ||
381 | #ifdef CONFIG_EVENT_PROFILE | 427 | #ifdef CONFIG_EVENT_PROFILE |
@@ -397,19 +443,22 @@ static inline int ftrace_get_offsets_##call( \ | |||
397 | * | 443 | * |
398 | */ | 444 | */ |
399 | 445 | ||
400 | #undef TRACE_EVENT | 446 | #undef TRACE_EVENT_TEMPLATE |
401 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ | 447 | #define TRACE_EVENT_TEMPLATE(call, proto, args, tstruct, assign, print) |
448 | |||
449 | #undef DEFINE_EVENT | ||
450 | #define DEFINE_EVENT(template, name, proto, args) \ | ||
402 | \ | 451 | \ |
403 | static void ftrace_profile_##call(proto); \ | 452 | static void ftrace_profile_##name(proto); \ |
404 | \ | 453 | \ |
405 | static int ftrace_profile_enable_##call(struct ftrace_event_call *unused)\ | 454 | static int ftrace_profile_enable_##name(struct ftrace_event_call *unused)\ |
406 | { \ | 455 | { \ |
407 | return register_trace_##call(ftrace_profile_##call); \ | 456 | return register_trace_##name(ftrace_profile_##name); \ |
408 | } \ | 457 | } \ |
409 | \ | 458 | \ |
410 | static void ftrace_profile_disable_##call(struct ftrace_event_call *unused)\ | 459 | static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\ |
411 | { \ | 460 | { \ |
412 | unregister_trace_##call(ftrace_profile_##call); \ | 461 | unregister_trace_##name(ftrace_profile_##name); \ |
413 | } | 462 | } |
414 | 463 | ||
415 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 464 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
@@ -550,15 +599,13 @@ static void ftrace_profile_disable_##call(struct ftrace_event_call *unused)\ | |||
550 | #define __assign_str(dst, src) \ | 599 | #define __assign_str(dst, src) \ |
551 | strcpy(__get_str(dst), src); | 600 | strcpy(__get_str(dst), src); |
552 | 601 | ||
553 | #undef TRACE_EVENT | 602 | #undef TRACE_EVENT_TEMPLATE |
554 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ | 603 | #define TRACE_EVENT_TEMPLATE(call, proto, args, tstruct, assign, print) \ |
555 | \ | ||
556 | static struct ftrace_event_call event_##call; \ | ||
557 | \ | 604 | \ |
558 | static void ftrace_raw_event_##call(proto) \ | 605 | static void ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \ |
606 | proto) \ | ||
559 | { \ | 607 | { \ |
560 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ | 608 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ |
561 | struct ftrace_event_call *event_call = &event_##call; \ | ||
562 | struct ring_buffer_event *event; \ | 609 | struct ring_buffer_event *event; \ |
563 | struct ftrace_raw_##call *entry; \ | 610 | struct ftrace_raw_##call *entry; \ |
564 | struct ring_buffer *buffer; \ | 611 | struct ring_buffer *buffer; \ |
@@ -572,7 +619,7 @@ static void ftrace_raw_event_##call(proto) \ | |||
572 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ | 619 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ |
573 | \ | 620 | \ |
574 | event = trace_current_buffer_lock_reserve(&buffer, \ | 621 | event = trace_current_buffer_lock_reserve(&buffer, \ |
575 | event_##call.id, \ | 622 | event_call->id, \ |
576 | sizeof(*entry) + __data_size, \ | 623 | sizeof(*entry) + __data_size, \ |
577 | irq_flags, pc); \ | 624 | irq_flags, pc); \ |
578 | if (!event) \ | 625 | if (!event) \ |
@@ -587,6 +634,14 @@ static void ftrace_raw_event_##call(proto) \ | |||
587 | if (!filter_current_check_discard(buffer, event_call, entry, event)) \ | 634 | if (!filter_current_check_discard(buffer, event_call, entry, event)) \ |
588 | trace_nowake_buffer_unlock_commit(buffer, \ | 635 | trace_nowake_buffer_unlock_commit(buffer, \ |
589 | event, irq_flags, pc); \ | 636 | event, irq_flags, pc); \ |
637 | } | ||
638 | |||
639 | #undef DEFINE_EVENT | ||
640 | #define DEFINE_EVENT(template, call, proto, args) \ | ||
641 | \ | ||
642 | static void ftrace_raw_event_##call(proto) \ | ||
643 | { \ | ||
644 | ftrace_raw_event_id_##template(&event_##call, args); \ | ||
590 | } \ | 645 | } \ |
591 | \ | 646 | \ |
592 | static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\ | 647 | static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\ |
@@ -630,8 +685,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
630 | .raw_init = ftrace_raw_init_event_##call, \ | 685 | .raw_init = ftrace_raw_init_event_##call, \ |
631 | .regfunc = ftrace_raw_reg_event_##call, \ | 686 | .regfunc = ftrace_raw_reg_event_##call, \ |
632 | .unregfunc = ftrace_raw_unreg_event_##call, \ | 687 | .unregfunc = ftrace_raw_unreg_event_##call, \ |
633 | .show_format = ftrace_format_##call, \ | 688 | .show_format = ftrace_format_##template, \ |
634 | .define_fields = ftrace_define_fields_##call, \ | 689 | .define_fields = ftrace_define_fields_##template, \ |
635 | _TRACE_PROFILE_INIT(call) \ | 690 | _TRACE_PROFILE_INIT(call) \ |
636 | } | 691 | } |
637 | 692 | ||
@@ -719,14 +774,15 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
719 | #undef __perf_count | 774 | #undef __perf_count |
720 | #define __perf_count(c) __count = (c) | 775 | #define __perf_count(c) __count = (c) |
721 | 776 | ||
722 | #undef TRACE_EVENT | 777 | #undef TRACE_EVENT_TEMPLATE |
723 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ | 778 | #define TRACE_EVENT_TEMPLATE(call, proto, args, tstruct, assign, print) \ |
724 | static void ftrace_profile_##call(proto) \ | 779 | static void \ |
780 | ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \ | ||
781 | proto) \ | ||
725 | { \ | 782 | { \ |
726 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ | 783 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ |
727 | extern int perf_swevent_get_recursion_context(void); \ | 784 | extern int perf_swevent_get_recursion_context(void); \ |
728 | extern void perf_swevent_put_recursion_context(int rctx); \ | 785 | extern void perf_swevent_put_recursion_context(int rctx); \ |
729 | struct ftrace_event_call *event_call = &event_##call; \ | ||
730 | extern void perf_tp_event(int, u64, u64, void *, int); \ | 786 | extern void perf_tp_event(int, u64, u64, void *, int); \ |
731 | struct ftrace_raw_##call *entry; \ | 787 | struct ftrace_raw_##call *entry; \ |
732 | u64 __addr = 0, __count = 1; \ | 788 | u64 __addr = 0, __count = 1; \ |
@@ -789,6 +845,15 @@ end_recursion: \ | |||
789 | \ | 845 | \ |
790 | } | 846 | } |
791 | 847 | ||
848 | #undef DEFINE_EVENT | ||
849 | #define DEFINE_EVENT(template, call, proto, args) \ | ||
850 | static void ftrace_profile_##call(proto) \ | ||
851 | { \ | ||
852 | struct ftrace_event_call *event_call = &event_##call; \ | ||
853 | \ | ||
854 | ftrace_profile_templ_##template(event_call, args); \ | ||
855 | } | ||
856 | |||
792 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 857 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
793 | #endif /* CONFIG_EVENT_PROFILE */ | 858 | #endif /* CONFIG_EVENT_PROFILE */ |
794 | 859 | ||