Commit 042957801626465492b9428860de39a3cb2a8219
Committed by
Steven Rostedt
1 parent
45677454dd
Exists in
master
and in
4 other branches
tracing/events: Show real number in array fields
Currently we have in something like the sched_switch event: field:char prev_comm[TASK_COMM_LEN]; offset:12; size:16; signed:1; When a userspace tool such as perf tries to parse this, the TASK_COMM_LEN is meaningless. This is done because the TRACE_EVENT() macro simply uses a #len to show the string of the length. When the length is an enum, we get a string that means nothing for tools. By adding a static buffer and a mutex to protect it, we can store the string into that buffer with snprintf and show the actual number. Now we get: field:char prev_comm[16]; offset:12; size:16; signed:1; Something much more useful. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Showing 4 changed files with 30 additions and 8 deletions Side-by-side Diff
include/linux/ftrace_event.h
... | ... | @@ -225,6 +225,10 @@ |
225 | 225 | FILTER_PTR_STRING, |
226 | 226 | }; |
227 | 227 | |
228 | +#define EVENT_STORAGE_SIZE 128 | |
229 | +extern struct mutex event_storage_mutex; | |
230 | +extern char event_storage[EVENT_STORAGE_SIZE]; | |
231 | + | |
228 | 232 | extern int trace_event_raw_init(struct ftrace_event_call *call); |
229 | 233 | extern int trace_define_field(struct ftrace_event_call *call, const char *type, |
230 | 234 | const char *name, int offset, int size, |
include/trace/ftrace.h
... | ... | @@ -296,13 +296,19 @@ |
296 | 296 | |
297 | 297 | #undef __array |
298 | 298 | #define __array(type, item, len) \ |
299 | - BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ | |
300 | - ret = trace_define_field(event_call, #type "[" #len "]", #item, \ | |
299 | + do { \ | |
300 | + mutex_lock(&event_storage_mutex); \ | |
301 | + BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ | |
302 | + snprintf(event_storage, sizeof(event_storage), \ | |
303 | + "%s[%d]", #type, len); \ | |
304 | + ret = trace_define_field(event_call, event_storage, #item, \ | |
301 | 305 | offsetof(typeof(field), item), \ |
302 | 306 | sizeof(field.item), \ |
303 | 307 | is_signed_type(type), FILTER_OTHER); \ |
304 | - if (ret) \ | |
305 | - return ret; | |
308 | + mutex_unlock(&event_storage_mutex); \ | |
309 | + if (ret) \ | |
310 | + return ret; \ | |
311 | + } while (0); | |
306 | 312 | |
307 | 313 | #undef __dynamic_array |
308 | 314 | #define __dynamic_array(type, item, len) \ |
kernel/trace/trace_events.c
... | ... | @@ -27,6 +27,12 @@ |
27 | 27 | |
28 | 28 | DEFINE_MUTEX(event_mutex); |
29 | 29 | |
30 | +DEFINE_MUTEX(event_storage_mutex); | |
31 | +EXPORT_SYMBOL_GPL(event_storage_mutex); | |
32 | + | |
33 | +char event_storage[EVENT_STORAGE_SIZE]; | |
34 | +EXPORT_SYMBOL_GPL(event_storage); | |
35 | + | |
30 | 36 | LIST_HEAD(ftrace_events); |
31 | 37 | LIST_HEAD(ftrace_common_fields); |
32 | 38 |
kernel/trace/trace_export.c
... | ... | @@ -83,13 +83,19 @@ |
83 | 83 | |
84 | 84 | #undef __array |
85 | 85 | #define __array(type, item, len) \ |
86 | - BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ | |
87 | - ret = trace_define_field(event_call, #type "[" #len "]", #item, \ | |
86 | + do { \ | |
87 | + BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ | |
88 | + mutex_lock(&event_storage_mutex); \ | |
89 | + snprintf(event_storage, sizeof(event_storage), \ | |
90 | + "%s[%d]", #type, len); \ | |
91 | + ret = trace_define_field(event_call, event_storage, #item, \ | |
88 | 92 | offsetof(typeof(field), item), \ |
89 | 93 | sizeof(field.item), \ |
90 | 94 | is_signed_type(type), FILTER_OTHER); \ |
91 | - if (ret) \ | |
92 | - return ret; | |
95 | + mutex_unlock(&event_storage_mutex); \ | |
96 | + if (ret) \ | |
97 | + return ret; \ | |
98 | + } while (0); | |
93 | 99 | |
94 | 100 | #undef __array_desc |
95 | 101 | #define __array_desc(type, container, item, len) \ |