diff options
-rw-r--r-- | include/trace/ftrace.h | 88 |
1 files changed, 85 insertions, 3 deletions
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 15ef08d9add1..5a7d18c43634 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
@@ -27,6 +27,9 @@ | |||
27 | #undef __field | 27 | #undef __field |
28 | #define __field(type, item) type item; | 28 | #define __field(type, item) type item; |
29 | 29 | ||
30 | #undef __string | ||
31 | #define __string(item, src) int __str_loc_##item; | ||
32 | |||
30 | #undef TP_STRUCT__entry | 33 | #undef TP_STRUCT__entry |
31 | #define TP_STRUCT__entry(args...) args | 34 | #define TP_STRUCT__entry(args...) args |
32 | 35 | ||
@@ -35,14 +38,53 @@ | |||
35 | struct ftrace_raw_##name { \ | 38 | struct ftrace_raw_##name { \ |
36 | struct trace_entry ent; \ | 39 | struct trace_entry ent; \ |
37 | tstruct \ | 40 | tstruct \ |
41 | char __str_data[0]; \ | ||
38 | }; \ | 42 | }; \ |
39 | static struct ftrace_event_call event_##name | 43 | static struct ftrace_event_call event_##name |
40 | 44 | ||
41 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 45 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
42 | 46 | ||
47 | |||
43 | /* | 48 | /* |
44 | * Stage 2 of the trace events. | 49 | * Stage 2 of the trace events. |
45 | * | 50 | * |
51 | * Include the following: | ||
52 | * | ||
53 | * struct ftrace_str_offsets_<call> { | ||
54 | * int <str1>; | ||
55 | * int <str2>; | ||
56 | * [...] | ||
57 | * }; | ||
58 | * | ||
59 | * The __string() macro will create each int <str>, this is to | ||
60 | * keep the offset of each string from the beggining of the event | ||
61 | * once we perform the strlen() of the src strings. | ||
62 | * | ||
63 | */ | ||
64 | |||
65 | #undef TRACE_FORMAT | ||
66 | #define TRACE_FORMAT(call, proto, args, fmt) | ||
67 | |||
68 | #undef __array | ||
69 | #define __array(type, item, len) | ||
70 | |||
71 | #undef __field | ||
72 | #define __field(type, item); | ||
73 | |||
74 | #undef __string | ||
75 | #define __string(item, src) int item; | ||
76 | |||
77 | #undef TRACE_EVENT | ||
78 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ | ||
79 | struct ftrace_str_offsets_##call { \ | ||
80 | tstruct; \ | ||
81 | }; | ||
82 | |||
83 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | ||
84 | |||
85 | /* | ||
86 | * Stage 3 of the trace events. | ||
87 | * | ||
46 | * Override the macros in <trace/trace_events.h> to include the following: | 88 | * Override the macros in <trace/trace_events.h> to include the following: |
47 | * | 89 | * |
48 | * enum print_line_t | 90 | * enum print_line_t |
@@ -80,6 +122,9 @@ | |||
80 | #undef TP_printk | 122 | #undef TP_printk |
81 | #define TP_printk(fmt, args...) fmt "\n", args | 123 | #define TP_printk(fmt, args...) fmt "\n", args |
82 | 124 | ||
125 | #undef __get_str | ||
126 | #define __get_str(field) (char *)__entry + __entry->__str_loc_##field | ||
127 | |||
83 | #undef TRACE_EVENT | 128 | #undef TRACE_EVENT |
84 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ | 129 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ |
85 | enum print_line_t \ | 130 | enum print_line_t \ |
@@ -146,6 +191,16 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
146 | if (!ret) \ | 191 | if (!ret) \ |
147 | return 0; | 192 | return 0; |
148 | 193 | ||
194 | #undef __string | ||
195 | #define __string(item, src) \ | ||
196 | ret = trace_seq_printf(s, "\tfield: __str_loc " #item ";\t" \ | ||
197 | "offset:%u;tsize:%u;\n", \ | ||
198 | (unsigned int)offsetof(typeof(field), \ | ||
199 | __str_loc_##item), \ | ||
200 | (unsigned int)sizeof(field.__str_loc_##item)); \ | ||
201 | if (!ret) \ | ||
202 | return 0; | ||
203 | |||
149 | #undef __entry | 204 | #undef __entry |
150 | #define __entry REC | 205 | #define __entry REC |
151 | 206 | ||
@@ -189,6 +244,12 @@ ftrace_format_##call(struct trace_seq *s) \ | |||
189 | if (ret) \ | 244 | if (ret) \ |
190 | return ret; | 245 | return ret; |
191 | 246 | ||
247 | #undef __string | ||
248 | #define __string(item, src) \ | ||
249 | ret = trace_define_field(event_call, "__str_loc", #item, \ | ||
250 | offsetof(typeof(field), __str_loc_##item), \ | ||
251 | sizeof(field.__str_loc_##item)); | ||
252 | |||
192 | #undef TRACE_EVENT | 253 | #undef TRACE_EVENT |
193 | #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ | 254 | #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ |
194 | int \ | 255 | int \ |
@@ -212,7 +273,7 @@ ftrace_define_fields_##call(void) \ | |||
212 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 273 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
213 | 274 | ||
214 | /* | 275 | /* |
215 | * Stage 3 of the trace events. | 276 | * Stage 4 of the trace events. |
216 | * | 277 | * |
217 | * Override the macros in <trace/trace_events.h> to include the following: | 278 | * Override the macros in <trace/trace_events.h> to include the following: |
218 | * | 279 | * |
@@ -409,6 +470,23 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
409 | #undef __entry | 470 | #undef __entry |
410 | #define __entry entry | 471 | #define __entry entry |
411 | 472 | ||
473 | #undef __field | ||
474 | #define __field(type, item) | ||
475 | |||
476 | #undef __array | ||
477 | #define __array(type, item, len) | ||
478 | |||
479 | #undef __string | ||
480 | #define __string(item, src) \ | ||
481 | __str_offsets.item = __str_size + \ | ||
482 | offsetof(typeof(*entry), __str_data); \ | ||
483 | __str_size += strlen(src) + 1; | ||
484 | |||
485 | #undef __assign_str | ||
486 | #define __assign_str(dst, src) \ | ||
487 | __entry->__str_loc_##dst = __str_offsets.dst; \ | ||
488 | strcpy(__get_str(dst), src); | ||
489 | |||
412 | #undef TRACE_EVENT | 490 | #undef TRACE_EVENT |
413 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ | 491 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ |
414 | _TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \ | 492 | _TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \ |
@@ -417,18 +495,22 @@ static struct ftrace_event_call event_##call; \ | |||
417 | \ | 495 | \ |
418 | static void ftrace_raw_event_##call(proto) \ | 496 | static void ftrace_raw_event_##call(proto) \ |
419 | { \ | 497 | { \ |
498 | struct ftrace_str_offsets_##call __maybe_unused __str_offsets; \ | ||
420 | struct ftrace_event_call *call = &event_##call; \ | 499 | struct ftrace_event_call *call = &event_##call; \ |
421 | struct ring_buffer_event *event; \ | 500 | struct ring_buffer_event *event; \ |
422 | struct ftrace_raw_##call *entry; \ | 501 | struct ftrace_raw_##call *entry; \ |
423 | unsigned long irq_flags; \ | 502 | unsigned long irq_flags; \ |
503 | int __str_size = 0; \ | ||
424 | int pc; \ | 504 | int pc; \ |
425 | \ | 505 | \ |
426 | local_save_flags(irq_flags); \ | 506 | local_save_flags(irq_flags); \ |
427 | pc = preempt_count(); \ | 507 | pc = preempt_count(); \ |
428 | \ | 508 | \ |
509 | tstruct; \ | ||
510 | \ | ||
429 | event = trace_current_buffer_lock_reserve(event_##call.id, \ | 511 | event = trace_current_buffer_lock_reserve(event_##call.id, \ |
430 | sizeof(struct ftrace_raw_##call), \ | 512 | sizeof(struct ftrace_raw_##call) + __str_size,\ |
431 | irq_flags, pc); \ | 513 | irq_flags, pc); \ |
432 | if (!event) \ | 514 | if (!event) \ |
433 | return; \ | 515 | return; \ |
434 | entry = ring_buffer_event_data(event); \ | 516 | entry = ring_buffer_event_data(event); \ |