aboutsummaryrefslogtreecommitdiffstats
path: root/include/trace
diff options
context:
space:
mode:
authorLi Zefan <lizf@cn.fujitsu.com>2009-06-01 03:35:46 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-06-01 23:25:15 -0400
commit7fcb7c472f455d1711eb5a7633204dba8800a6d6 (patch)
treeba64de513bdbe5550c6fc08078a356359830ec99 /include/trace
parenta9c1c3abe1160a5632e48c929b02b740556bf423 (diff)
tracing/events: introduce __dynamic_array()
__string() is limited: - it's a char array, but we may want to define array with other types - a source string should be available, but we may just know the string size We introduce __dynamic_array() to break those limitations, and __string() becomes a wrapper of it. As a side effect, now __get_str() can be used in TP_fast_assign but not only TP_print. Take XFS for example, we have the string length in the dirent, but the string itself is not NULL-terminated, so __dynamic_array() can be used: TRACE_EVENT(xfs_dir2, TP_PROTO(struct xfs_da_args *args), TP_ARGS(args), TP_STRUCT__entry( __field(int, namelen) __dynamic_array(char, name, args->namelen + 1) ... ), TP_fast_assign( char *name = __get_str(name); if (args->namelen) memcpy(name, args->name, args->namelen); name[args->namelen] = '\0'; __entry->namelen = args->namelen; ), TP_printk("name %.*s namelen %d", __entry->namelen ? __get_str(name) : NULL __entry->namelen) ); [ Impact: allow defining dynamic size arrays ] Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> LKML-Reference: <4A2384D2.3080403@cn.fujitsu.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'include/trace')
-rw-r--r--include/trace/ftrace.h122
1 files changed, 88 insertions, 34 deletions
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index ee9268222448..b5478dab579b 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -18,14 +18,17 @@
18 18
19#include <linux/ftrace_event.h> 19#include <linux/ftrace_event.h>
20 20
21#undef __field
22#define __field(type, item) type item;
23
21#undef __array 24#undef __array
22#define __array(type, item, len) type item[len]; 25#define __array(type, item, len) type item[len];
23 26
24#undef __field 27#undef __dynamic_array
25#define __field(type, item) type item; 28#define __dynamic_array(type, item, len) unsigned short __data_loc_##item;
26 29
27#undef __string 30#undef __string
28#define __string(item, src) unsigned short __str_loc_##item; 31#define __string(item, src) __dynamic_array(char, item, -1)
29 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
@@ -35,7 +38,7 @@
35 struct ftrace_raw_##name { \ 38 struct ftrace_raw_##name { \
36 struct trace_entry ent; \ 39 struct trace_entry ent; \
37 tstruct \ 40 tstruct \
38 char __str_data[0]; \ 41 char __data[0]; \
39 }; \ 42 }; \
40 static struct ftrace_event_call event_##name 43 static struct ftrace_event_call event_##name
41 44
@@ -47,30 +50,31 @@
47 * 50 *
48 * Include the following: 51 * Include the following:
49 * 52 *
50 * struct ftrace_str_offsets_<call> { 53 * struct ftrace_data_offsets_<call> {
51 * int <str1>; 54 * int <item1>;
52 * int <str2>; 55 * int <item2>;
53 * [...] 56 * [...]
54 * }; 57 * };
55 * 58 *
56 * The __string() macro will create each int <str>, this is to 59 * The __dynamic_array() macro will create each int <item>, this is
57 * keep the offset of each string from the beggining of the event 60 * to keep the offset of each array from the beginning of the event.
58 * once we perform the strlen() of the src strings.
59 *
60 */ 61 */
61 62
63#undef __field
64#define __field(type, item);
65
62#undef __array 66#undef __array
63#define __array(type, item, len) 67#define __array(type, item, len)
64 68
65#undef __field 69#undef __dynamic_array
66#define __field(type, item); 70#define __dynamic_array(type, item, len) int item;
67 71
68#undef __string 72#undef __string
69#define __string(item, src) int item; 73#define __string(item, src) __dynamic_array(char, item, -1)
70 74
71#undef TRACE_EVENT 75#undef TRACE_EVENT
72#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ 76#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
73 struct ftrace_str_offsets_##call { \ 77 struct ftrace_data_offsets_##call { \
74 tstruct; \ 78 tstruct; \
75 }; 79 };
76 80
@@ -119,8 +123,12 @@
119#undef TP_printk 123#undef TP_printk
120#define TP_printk(fmt, args...) fmt "\n", args 124#define TP_printk(fmt, args...) fmt "\n", args
121 125
126#undef __get_dynamic_array
127#define __get_dynamic_array(field) \
128 ((void *)__entry + __entry->__data_loc_##field)
129
122#undef __get_str 130#undef __get_str
123#define __get_str(field) ((char *)__entry + __entry->__str_loc_##field) 131#define __get_str(field) (char *)__get_dynamic_array(field)
124 132
125#undef __print_flags 133#undef __print_flags
126#define __print_flags(flag, delim, flag_array...) \ 134#define __print_flags(flag, delim, flag_array...) \
@@ -207,16 +215,19 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
207 if (!ret) \ 215 if (!ret) \
208 return 0; 216 return 0;
209 217
210#undef __string 218#undef __dynamic_array
211#define __string(item, src) \ 219#define __dynamic_array(type, item, len) \
212 ret = trace_seq_printf(s, "\tfield:__str_loc " #item ";\t" \ 220 ret = trace_seq_printf(s, "\tfield:__data_loc " #item ";\t" \
213 "offset:%u;\tsize:%u;\n", \ 221 "offset:%u;\tsize:%u;\n", \
214 (unsigned int)offsetof(typeof(field), \ 222 (unsigned int)offsetof(typeof(field), \
215 __str_loc_##item), \ 223 __data_loc_##item), \
216 (unsigned int)sizeof(field.__str_loc_##item)); \ 224 (unsigned int)sizeof(field.__data_loc_##item)); \
217 if (!ret) \ 225 if (!ret) \
218 return 0; 226 return 0;
219 227
228#undef __string
229#define __string(item, src) __dynamic_array(char, item, -1)
230
220#undef __entry 231#undef __entry
221#define __entry REC 232#define __entry REC
222 233
@@ -260,11 +271,14 @@ ftrace_format_##call(struct trace_seq *s) \
260 if (ret) \ 271 if (ret) \
261 return ret; 272 return ret;
262 273
274#undef __dynamic_array
275#define __dynamic_array(type, item, len) \
276 ret = trace_define_field(event_call, "__data_loc" "[" #type "]", #item,\
277 offsetof(typeof(field), __data_loc_##item), \
278 sizeof(field.__data_loc_##item), 0);
279
263#undef __string 280#undef __string
264#define __string(item, src) \ 281#define __string(item, src) __dynamic_array(char, item, -1)
265 ret = trace_define_field(event_call, "__str_loc", #item, \
266 offsetof(typeof(field), __str_loc_##item), \
267 sizeof(field.__str_loc_##item), 0);
268 282
269#undef TRACE_EVENT 283#undef TRACE_EVENT
270#define TRACE_EVENT(call, proto, args, tstruct, func, print) \ 284#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
@@ -289,6 +303,43 @@ ftrace_define_fields_##call(void) \
289#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 303#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
290 304
291/* 305/*
306 * remember the offset of each array from the beginning of the event.
307 */
308
309#undef __entry
310#define __entry entry
311
312#undef __field
313#define __field(type, item)
314
315#undef __array
316#define __array(type, item, len)
317
318#undef __dynamic_array
319#define __dynamic_array(type, item, len) \
320 __data_offsets->item = __data_size + \
321 offsetof(typeof(*entry), __data); \
322 __data_size += (len) * sizeof(type);
323
324#undef __string
325#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1) \
326
327#undef TRACE_EVENT
328#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
329static inline int ftrace_get_offsets_##call( \
330 struct ftrace_data_offsets_##call *__data_offsets, proto) \
331{ \
332 int __data_size = 0; \
333 struct ftrace_raw_##call __maybe_unused *entry; \
334 \
335 tstruct; \
336 \
337 return __data_size; \
338}
339
340#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
341
342/*
292 * Stage 4 of the trace events. 343 * Stage 4 of the trace events.
293 * 344 *
294 * Override the macros in <trace/trace_events.h> to include the following: 345 * Override the macros in <trace/trace_events.h> to include the following:
@@ -432,15 +483,15 @@ static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\
432#undef __array 483#undef __array
433#define __array(type, item, len) 484#define __array(type, item, len)
434 485
486#undef __dynamic_array
487#define __dynamic_array(type, item, len) \
488 __entry->__data_loc_##item = __data_offsets.item;
489
435#undef __string 490#undef __string
436#define __string(item, src) \ 491#define __string(item, src) __dynamic_array(char, item, -1) \
437 __str_offsets.item = __str_size + \
438 offsetof(typeof(*entry), __str_data); \
439 __str_size += strlen(src) + 1;
440 492
441#undef __assign_str 493#undef __assign_str
442#define __assign_str(dst, src) \ 494#define __assign_str(dst, src) \
443 __entry->__str_loc_##dst = __str_offsets.dst; \
444 strcpy(__get_str(dst), src); 495 strcpy(__get_str(dst), src);
445 496
446#undef TRACE_EVENT 497#undef TRACE_EVENT
@@ -451,26 +502,29 @@ static struct ftrace_event_call event_##call; \
451 \ 502 \
452static void ftrace_raw_event_##call(proto) \ 503static void ftrace_raw_event_##call(proto) \
453{ \ 504{ \
454 struct ftrace_str_offsets_##call __maybe_unused __str_offsets; \ 505 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
455 struct ftrace_event_call *event_call = &event_##call; \ 506 struct ftrace_event_call *event_call = &event_##call; \
456 struct ring_buffer_event *event; \ 507 struct ring_buffer_event *event; \
457 struct ftrace_raw_##call *entry; \ 508 struct ftrace_raw_##call *entry; \
458 unsigned long irq_flags; \ 509 unsigned long irq_flags; \
459 int __str_size = 0; \ 510 int __data_size; \
460 int pc; \ 511 int pc; \
461 \ 512 \
462 local_save_flags(irq_flags); \ 513 local_save_flags(irq_flags); \
463 pc = preempt_count(); \ 514 pc = preempt_count(); \
464 \ 515 \
465 tstruct; \ 516 __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
466 \ 517 \
467 event = trace_current_buffer_lock_reserve(event_##call.id, \ 518 event = trace_current_buffer_lock_reserve(event_##call.id, \
468 sizeof(struct ftrace_raw_##call) + __str_size,\ 519 sizeof(*entry) + __data_size, \
469 irq_flags, pc); \ 520 irq_flags, pc); \
470 if (!event) \ 521 if (!event) \
471 return; \ 522 return; \
472 entry = ring_buffer_event_data(event); \ 523 entry = ring_buffer_event_data(event); \
473 \ 524 \
525 \
526 tstruct \
527 \
474 { assign; } \ 528 { assign; } \
475 \ 529 \
476 if (!filter_current_check_discard(event_call, entry, event)) \ 530 if (!filter_current_check_discard(event_call, entry, event)) \