diff options
| author | Tom Zanussi <tzanussi@gmail.com> | 2009-03-22 04:30:39 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-03-22 13:11:22 -0400 |
| commit | cf027f645e6aee4f0ca6197a6b6a57f327fdb13f (patch) | |
| tree | f8a20e8707967db5d9140f9069426f410a30dd32 | |
| parent | 0cf53ff62b3e9e491ff5e5f05b193fb6ce643047 (diff) | |
tracing: add run-time field descriptions for event filtering
This patch makes the field descriptions defined for event tracing
available at run-time, for the event-filtering mechanism introduced
in a subsequent patch.
The common event fields are prepended with 'common_' in the format
display, allowing them to be distinguished from the other fields
that might internally have same name and can therefore be
unambiguously used in filters.
Signed-off-by: Tom Zanussi <tzanussi@gmail.com>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <1237710639.7703.46.camel@charm-linux>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | kernel/trace/trace.h | 30 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 40 | ||||
| -rw-r--r-- | kernel/trace/trace_events_stage_2.h | 45 | ||||
| -rw-r--r-- | kernel/trace/trace_events_stage_3.h | 2 |
4 files changed, 107 insertions, 10 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 7cfb741be200..9288dc7ad14f 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -775,16 +775,26 @@ enum { | |||
| 775 | TRACE_EVENT_TYPE_RAW = 2, | 775 | TRACE_EVENT_TYPE_RAW = 2, |
| 776 | }; | 776 | }; |
| 777 | 777 | ||
| 778 | struct ftrace_event_field { | ||
| 779 | struct list_head link; | ||
| 780 | char *name; | ||
| 781 | char *type; | ||
| 782 | int offset; | ||
| 783 | int size; | ||
| 784 | }; | ||
| 785 | |||
| 778 | struct ftrace_event_call { | 786 | struct ftrace_event_call { |
| 779 | char *name; | 787 | char *name; |
| 780 | char *system; | 788 | char *system; |
| 781 | struct dentry *dir; | 789 | struct dentry *dir; |
| 782 | int enabled; | 790 | int enabled; |
| 783 | int (*regfunc)(void); | 791 | int (*regfunc)(void); |
| 784 | void (*unregfunc)(void); | 792 | void (*unregfunc)(void); |
| 785 | int id; | 793 | int id; |
| 786 | int (*raw_init)(void); | 794 | int (*raw_init)(void); |
| 787 | int (*show_format)(struct trace_seq *s); | 795 | int (*show_format)(struct trace_seq *s); |
| 796 | int (*define_fields)(void); | ||
| 797 | struct list_head fields; | ||
| 788 | 798 | ||
| 789 | #ifdef CONFIG_EVENT_PROFILE | 799 | #ifdef CONFIG_EVENT_PROFILE |
| 790 | atomic_t profile_count; | 800 | atomic_t profile_count; |
| @@ -793,6 +803,8 @@ struct ftrace_event_call { | |||
| 793 | #endif | 803 | #endif |
| 794 | }; | 804 | }; |
| 795 | 805 | ||
| 806 | int trace_define_field(struct ftrace_event_call *call, char *type, | ||
| 807 | char *name, int offset, int size); | ||
| 796 | void event_trace_printk(unsigned long ip, const char *fmt, ...); | 808 | void event_trace_printk(unsigned long ip, const char *fmt, ...); |
| 797 | extern struct ftrace_event_call __start_ftrace_events[]; | 809 | extern struct ftrace_event_call __start_ftrace_events[]; |
| 798 | extern struct ftrace_event_call __stop_ftrace_events[]; | 810 | extern struct ftrace_event_call __stop_ftrace_events[]; |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 3047b56f6637..961b057da28b 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -19,6 +19,34 @@ | |||
| 19 | 19 | ||
| 20 | static DEFINE_MUTEX(event_mutex); | 20 | static DEFINE_MUTEX(event_mutex); |
| 21 | 21 | ||
| 22 | int trace_define_field(struct ftrace_event_call *call, char *type, | ||
| 23 | char *name, int offset, int size) | ||
| 24 | { | ||
| 25 | struct ftrace_event_field *field; | ||
| 26 | |||
| 27 | field = kmalloc(sizeof(*field), GFP_KERNEL); | ||
| 28 | if (!field) | ||
| 29 | goto err; | ||
| 30 | field->name = kstrdup(name, GFP_KERNEL); | ||
| 31 | if (!field->name) | ||
| 32 | goto err; | ||
| 33 | field->type = kstrdup(type, GFP_KERNEL); | ||
| 34 | if (!field->type) | ||
| 35 | goto err; | ||
| 36 | field->offset = offset; | ||
| 37 | field->size = size; | ||
| 38 | list_add(&field->link, &call->fields); | ||
| 39 | |||
| 40 | return 0; | ||
| 41 | err: | ||
| 42 | if (field) { | ||
| 43 | kfree(field->name); | ||
| 44 | kfree(field->type); | ||
| 45 | } | ||
| 46 | kfree(field); | ||
| 47 | return -ENOMEM; | ||
| 48 | } | ||
| 49 | |||
| 22 | static void ftrace_clear_events(void) | 50 | static void ftrace_clear_events(void) |
| 23 | { | 51 | { |
| 24 | struct ftrace_event_call *call = (void *)__start_ftrace_events; | 52 | struct ftrace_event_call *call = (void *)__start_ftrace_events; |
| @@ -343,7 +371,8 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
| 343 | 371 | ||
| 344 | #undef FIELD | 372 | #undef FIELD |
| 345 | #define FIELD(type, name) \ | 373 | #define FIELD(type, name) \ |
| 346 | #type, #name, offsetof(typeof(field), name), sizeof(field.name) | 374 | #type, "common_" #name, offsetof(typeof(field), name), \ |
| 375 | sizeof(field.name) | ||
| 347 | 376 | ||
| 348 | static int trace_write_header(struct trace_seq *s) | 377 | static int trace_write_header(struct trace_seq *s) |
| 349 | { | 378 | { |
| @@ -581,6 +610,15 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events) | |||
| 581 | call->name); | 610 | call->name); |
| 582 | } | 611 | } |
| 583 | 612 | ||
| 613 | if (call->define_fields) { | ||
| 614 | ret = call->define_fields(); | ||
| 615 | if (ret < 0) { | ||
| 616 | pr_warning("Could not initialize trace point" | ||
| 617 | " events/%s\n", call->name); | ||
| 618 | return ret; | ||
| 619 | } | ||
| 620 | } | ||
| 621 | |||
| 584 | /* A trace may not want to export its format */ | 622 | /* A trace may not want to export its format */ |
| 585 | if (!call->show_format) | 623 | if (!call->show_format) |
| 586 | return 0; | 624 | return 0; |
diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h index 5117c43f5c67..30743f7d4110 100644 --- a/kernel/trace/trace_events_stage_2.h +++ b/kernel/trace/trace_events_stage_2.h | |||
| @@ -129,3 +129,48 @@ ftrace_format_##call(struct trace_seq *s) \ | |||
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | #include <trace/trace_event_types.h> | 131 | #include <trace/trace_event_types.h> |
| 132 | |||
| 133 | #undef __field | ||
| 134 | #define __field(type, item) \ | ||
| 135 | ret = trace_define_field(event_call, #type, #item, \ | ||
| 136 | offsetof(typeof(field), item), \ | ||
| 137 | sizeof(field.item)); \ | ||
| 138 | if (ret) \ | ||
| 139 | return ret; | ||
| 140 | |||
| 141 | #undef __array | ||
| 142 | #define __array(type, item, len) \ | ||
| 143 | ret = trace_define_field(event_call, #type "[" #len "]", #item, \ | ||
| 144 | offsetof(typeof(field), item), \ | ||
| 145 | sizeof(field.item)); \ | ||
| 146 | if (ret) \ | ||
| 147 | return ret; | ||
| 148 | |||
| 149 | #define __common_field(type, item) \ | ||
| 150 | ret = trace_define_field(event_call, #type, "common_" #item, \ | ||
| 151 | offsetof(typeof(field.ent), item), \ | ||
| 152 | sizeof(field.ent.item)); \ | ||
| 153 | if (ret) \ | ||
| 154 | return ret; | ||
| 155 | |||
| 156 | #undef TRACE_EVENT | ||
| 157 | #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ | ||
| 158 | int \ | ||
| 159 | ftrace_define_fields_##call(void) \ | ||
| 160 | { \ | ||
| 161 | struct ftrace_raw_##call field; \ | ||
| 162 | struct ftrace_event_call *event_call = &event_##call; \ | ||
| 163 | int ret; \ | ||
| 164 | \ | ||
| 165 | __common_field(unsigned char, type); \ | ||
| 166 | __common_field(unsigned char, flags); \ | ||
| 167 | __common_field(unsigned char, preempt_count); \ | ||
| 168 | __common_field(int, pid); \ | ||
| 169 | __common_field(int, tgid); \ | ||
| 170 | \ | ||
| 171 | tstruct; \ | ||
| 172 | \ | ||
| 173 | return ret; \ | ||
| 174 | } | ||
| 175 | |||
| 176 | #include <trace/trace_event_types.h> | ||
diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h index 6b3261ca988c..468938f70141 100644 --- a/kernel/trace/trace_events_stage_3.h +++ b/kernel/trace/trace_events_stage_3.h | |||
| @@ -252,6 +252,7 @@ static int ftrace_raw_init_event_##call(void) \ | |||
| 252 | if (!id) \ | 252 | if (!id) \ |
| 253 | return -ENODEV; \ | 253 | return -ENODEV; \ |
| 254 | event_##call.id = id; \ | 254 | event_##call.id = id; \ |
| 255 | INIT_LIST_HEAD(&event_##call.fields); \ | ||
| 255 | return 0; \ | 256 | return 0; \ |
| 256 | } \ | 257 | } \ |
| 257 | \ | 258 | \ |
| @@ -264,6 +265,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
| 264 | .regfunc = ftrace_raw_reg_event_##call, \ | 265 | .regfunc = ftrace_raw_reg_event_##call, \ |
| 265 | .unregfunc = ftrace_raw_unreg_event_##call, \ | 266 | .unregfunc = ftrace_raw_unreg_event_##call, \ |
| 266 | .show_format = ftrace_format_##call, \ | 267 | .show_format = ftrace_format_##call, \ |
| 268 | .define_fields = ftrace_define_fields_##call, \ | ||
| 267 | _TRACE_PROFILE_INIT(call) \ | 269 | _TRACE_PROFILE_INIT(call) \ |
| 268 | } | 270 | } |
| 269 | 271 | ||
