Message ID | 20090701010917.32547.17150.stgit@localhost.localdomain (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Jun 30, 2009 at 09:09:17PM -0400, Masami Hiramatsu wrote: > Add dynamic ftrace_event_call support to ftrace. Trace engines can adds new > ftrace_event_call to ftrace on the fly. Each operator functions of the call > takes a ftrace_event_call data structure as an argument, because these > functions may be shared among several ftrace_event_calls. > > Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> > Cc: Steven Rostedt <rostedt@goodmis.org> > Cc: Ingo Molnar <mingo@elte.hu> > Cc: Tom Zanussi <tzanussi@gmail.com> > Cc: Frederic Weisbecker <fweisbec@gmail.com> Looks good too. Acked-by: Frederic Weisbecker <fweisbec@gmail.com> > --- > > include/linux/ftrace_event.h | 13 +++++--- > include/trace/ftrace.h | 22 +++++++------ > kernel/trace/trace_events.c | 70 ++++++++++++++++++++++++++++++++---------- > kernel/trace/trace_export.c | 27 ++++++++-------- > 4 files changed, 85 insertions(+), 47 deletions(-) > > diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h > index 5c093ff..f7733b6 100644 > --- a/include/linux/ftrace_event.h > +++ b/include/linux/ftrace_event.h > @@ -108,12 +108,13 @@ struct ftrace_event_call { > struct dentry *dir; > struct trace_event *event; > int enabled; > - int (*regfunc)(void); > - void (*unregfunc)(void); > + int (*regfunc)(struct ftrace_event_call *); > + void (*unregfunc)(struct ftrace_event_call *); > int id; > - int (*raw_init)(void); > - int (*show_format)(struct trace_seq *s); > - int (*define_fields)(void); > + int (*raw_init)(struct ftrace_event_call *); > + int (*show_format)(struct ftrace_event_call *, > + struct trace_seq *); > + int (*define_fields)(struct ftrace_event_call *); > struct list_head fields; > int filter_active; > void *filter; > @@ -138,6 +139,8 @@ extern int filter_current_check_discard(struct ftrace_event_call *call, > > extern int trace_define_field(struct ftrace_event_call *call, char *type, > char *name, int offset, int size, int is_signed); > +extern int trace_add_event_call(struct ftrace_event_call *call); > +extern void trace_remove_event_call(struct ftrace_event_call *call); > > #define is_signed_type(type) (((type)(-1)) < 0) > > diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h > index 1867553..d696580 100644 > --- a/include/trace/ftrace.h > +++ b/include/trace/ftrace.h > @@ -147,7 +147,8 @@ > #undef TRACE_EVENT > #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ > static int \ > -ftrace_format_##call(struct trace_seq *s) \ > +ftrace_format_##call(struct ftrace_event_call *event_call, \ > + struct trace_seq *s) \ > { \ > struct ftrace_raw_##call field __attribute__((unused)); \ > int ret = 0; \ > @@ -289,10 +290,9 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ > #undef TRACE_EVENT > #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ > int \ > -ftrace_define_fields_##call(void) \ > +ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ > { \ > struct ftrace_raw_##call field; \ > - struct ftrace_event_call *event_call = &event_##call; \ > int ret; \ > \ > __common_field(int, type, 1); \ > @@ -355,7 +355,7 @@ static inline int ftrace_get_offsets_##call( \ > * event_trace_printk(_RET_IP_, "<call>: " <fmt>); > * } > * > - * static int ftrace_reg_event_<call>(void) > + * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused) > * { > * int ret; > * > @@ -366,7 +366,7 @@ static inline int ftrace_get_offsets_##call( \ > * return ret; > * } > * > - * static void ftrace_unreg_event_<call>(void) > + * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) > * { > * unregister_trace_<call>(ftrace_event_<call>); > * } > @@ -399,7 +399,7 @@ static inline int ftrace_get_offsets_##call( \ > * trace_current_buffer_unlock_commit(event, irq_flags, pc); > * } > * > - * static int ftrace_raw_reg_event_<call>(void) > + * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused) > * { > * int ret; > * > @@ -410,7 +410,7 @@ static inline int ftrace_get_offsets_##call( \ > * return ret; > * } > * > - * static void ftrace_unreg_event_<call>(void) > + * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) > * { > * unregister_trace_<call>(ftrace_raw_event_<call>); > * } > @@ -419,7 +419,7 @@ static inline int ftrace_get_offsets_##call( \ > * .trace = ftrace_raw_output_<call>, <-- stage 2 > * }; > * > - * static int ftrace_raw_init_event_<call>(void) > + * static int ftrace_raw_init_event_<call>(struct ftrace_event_call *unused) > * { > * int id; > * > @@ -537,7 +537,7 @@ static void ftrace_raw_event_##call(proto) \ > trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \ > } \ > \ > -static int ftrace_raw_reg_event_##call(void) \ > +static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\ > { \ > int ret; \ > \ > @@ -548,7 +548,7 @@ static int ftrace_raw_reg_event_##call(void) \ > return ret; \ > } \ > \ > -static void ftrace_raw_unreg_event_##call(void) \ > +static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\ > { \ > unregister_trace_##call(ftrace_raw_event_##call); \ > } \ > @@ -557,7 +557,7 @@ static struct trace_event ftrace_event_type_##call = { \ > .trace = ftrace_raw_output_##call, \ > }; \ > \ > -static int ftrace_raw_init_event_##call(void) \ > +static int ftrace_raw_init_event_##call(struct ftrace_event_call *unused)\ > { \ > int id; \ > \ > diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c > index 53c8fd3..94ff41e 100644 > --- a/kernel/trace/trace_events.c > +++ b/kernel/trace/trace_events.c > @@ -60,9 +60,7 @@ err: > } > EXPORT_SYMBOL_GPL(trace_define_field); > > -#ifdef CONFIG_MODULES > - > -static void trace_destroy_fields(struct ftrace_event_call *call) > +void trace_destroy_fields(struct ftrace_event_call *call) > { > struct ftrace_event_field *field, *next; > > @@ -74,8 +72,6 @@ static void trace_destroy_fields(struct ftrace_event_call *call) > } > } > > -#endif /* CONFIG_MODULES */ > - > static void ftrace_event_enable_disable(struct ftrace_event_call *call, > int enable) > { > @@ -84,14 +80,14 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call, > if (call->enabled) { > call->enabled = 0; > tracing_stop_cmdline_record(); > - call->unregfunc(); > + call->unregfunc(call); > } > break; > case 1: > if (!call->enabled) { > call->enabled = 1; > tracing_start_cmdline_record(); > - call->regfunc(); > + call->regfunc(call); > } > break; > } > @@ -574,7 +570,7 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt, > trace_seq_printf(s, "format:\n"); > trace_write_header(s); > > - r = call->show_format(s); > + r = call->show_format(call, s); > if (!r) { > /* > * ug! The format output is bigger than a PAGE!! > @@ -921,7 +917,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, > d_events = event_subsystem_dir(call->system, d_events); > > if (call->raw_init) { > - ret = call->raw_init(); > + ret = call->raw_init(call); > if (ret < 0) { > pr_warning("Could not initialize trace point" > " events/%s\n", call->name); > @@ -945,7 +941,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, > id); > > if (call->define_fields) { > - ret = call->define_fields(); > + ret = call->define_fields(call); > if (ret < 0) { > pr_warning("Could not initialize trace point" > " events/%s\n", call->name); > @@ -965,6 +961,52 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, > return 0; > } > > +static int __trace_add_event_call(struct ftrace_event_call *call) > +{ > + struct dentry *d_events; > + > + if (!call->name) > + return -EINVAL; > + > + d_events = event_trace_events_dir(); > + if (!d_events) > + return -ENOENT; > + > + list_add(&call->list, &ftrace_events); > + return event_create_dir(call, d_events, &ftrace_event_id_fops, > + &ftrace_enable_fops, &ftrace_event_filter_fops, > + &ftrace_event_format_fops); > +} > + > +/* Add an additional event_call dynamically */ > +int trace_add_event_call(struct ftrace_event_call *call) > +{ > + int ret; > + mutex_lock(&event_mutex); > + ret = __trace_add_event_call(call); > + mutex_unlock(&event_mutex); > + return ret; > +} > + > +static void __trace_remove_event_call(struct ftrace_event_call *call) > +{ > + ftrace_event_enable_disable(call, 0); > + if (call->event) > + __unregister_ftrace_event(call->event); > + debugfs_remove_recursive(call->dir); > + list_del(&call->list); > + trace_destroy_fields(call); > + destroy_preds(call); > +} > + > +/* Remove an event_call */ > +void trace_remove_event_call(struct ftrace_event_call *call) > +{ > + mutex_lock(&event_mutex); > + __trace_remove_event_call(call); > + mutex_unlock(&event_mutex); > +} > + > #define for_each_event(event, start, end) \ > for (event = start; \ > (unsigned long)event < (unsigned long)end; \ > @@ -1070,13 +1112,7 @@ static void trace_module_remove_events(struct module *mod) > list_for_each_entry_safe(call, p, &ftrace_events, list) { > if (call->mod == mod) { > found = true; > - ftrace_event_enable_disable(call, 0); > - if (call->event) > - __unregister_ftrace_event(call->event); > - debugfs_remove_recursive(call->dir); > - list_del(&call->list); > - trace_destroy_fields(call); > - destroy_preds(call); > + __trace_remove_event_call(call); > } > } > > diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c > index d06cf89..7cee79d 100644 > --- a/kernel/trace/trace_export.c > +++ b/kernel/trace/trace_export.c > @@ -60,7 +60,7 @@ extern void __bad_type_size(void); > #undef TRACE_EVENT_FORMAT > #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ > static int \ > -ftrace_format_##call(struct trace_seq *s) \ > +ftrace_format_##call(struct ftrace_event_call *dummy, struct trace_seq *s)\ > { \ > struct args field; \ > int ret; \ > @@ -76,7 +76,7 @@ ftrace_format_##call(struct trace_seq *s) \ > #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ > tpfmt) \ > static int \ > -ftrace_format_##call(struct trace_seq *s) \ > +ftrace_format_##call(struct ftrace_event_call *dummy, struct trace_seq *s)\ > { \ > struct args field; \ > int ret; \ > @@ -115,10 +115,16 @@ ftrace_format_##call(struct trace_seq *s) \ > #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ > cmd; > > +static int ftrace_raw_init_event(struct ftrace_event_call *event_call) > +{ > + INIT_LIST_HEAD(&event_call->fields); > + init_preds(event_call); > + return 0; > +} > + > #undef TRACE_EVENT_FORMAT > #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ > -int ftrace_define_fields_##call(void); \ > -static int ftrace_raw_init_event_##call(void); \ > +int ftrace_define_fields_##call(struct ftrace_event_call *c); \ > \ > struct ftrace_event_call __used \ > __attribute__((__aligned__(4))) \ > @@ -126,16 +132,10 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ > .name = #call, \ > .id = proto, \ > .system = __stringify(TRACE_SYSTEM), \ > - .raw_init = ftrace_raw_init_event_##call, \ > + .raw_init = ftrace_raw_init_event, \ > .show_format = ftrace_format_##call, \ > .define_fields = ftrace_define_fields_##call, \ > -}; \ > -static int ftrace_raw_init_event_##call(void) \ > -{ \ > - INIT_LIST_HEAD(&event_##call.fields); \ > - init_preds(&event_##call); \ > - return 0; \ > -} \ > +}; > > #undef TRACE_EVENT_FORMAT_NOFILTER > #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ > @@ -182,9 +182,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ > #undef TRACE_EVENT_FORMAT > #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ > int \ > -ftrace_define_fields_##call(void) \ > +ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ > { \ > - struct ftrace_event_call *event_call = &event_##call; \ > struct args field; \ > int ret; \ > \ > > > -- > Masami Hiramatsu > > Software Engineer > Hitachi Computer Products (America), Inc. > Software Solutions Division > > e-mail: mhiramat@redhat.com -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 5c093ff..f7733b6 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -108,12 +108,13 @@ struct ftrace_event_call { struct dentry *dir; struct trace_event *event; int enabled; - int (*regfunc)(void); - void (*unregfunc)(void); + int (*regfunc)(struct ftrace_event_call *); + void (*unregfunc)(struct ftrace_event_call *); int id; - int (*raw_init)(void); - int (*show_format)(struct trace_seq *s); - int (*define_fields)(void); + int (*raw_init)(struct ftrace_event_call *); + int (*show_format)(struct ftrace_event_call *, + struct trace_seq *); + int (*define_fields)(struct ftrace_event_call *); struct list_head fields; int filter_active; void *filter; @@ -138,6 +139,8 @@ extern int filter_current_check_discard(struct ftrace_event_call *call, extern int trace_define_field(struct ftrace_event_call *call, char *type, char *name, int offset, int size, int is_signed); +extern int trace_add_event_call(struct ftrace_event_call *call); +extern void trace_remove_event_call(struct ftrace_event_call *call); #define is_signed_type(type) (((type)(-1)) < 0) diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 1867553..d696580 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -147,7 +147,8 @@ #undef TRACE_EVENT #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ static int \ -ftrace_format_##call(struct trace_seq *s) \ +ftrace_format_##call(struct ftrace_event_call *event_call, \ + struct trace_seq *s) \ { \ struct ftrace_raw_##call field __attribute__((unused)); \ int ret = 0; \ @@ -289,10 +290,9 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ #undef TRACE_EVENT #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ int \ -ftrace_define_fields_##call(void) \ +ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ { \ struct ftrace_raw_##call field; \ - struct ftrace_event_call *event_call = &event_##call; \ int ret; \ \ __common_field(int, type, 1); \ @@ -355,7 +355,7 @@ static inline int ftrace_get_offsets_##call( \ * event_trace_printk(_RET_IP_, "<call>: " <fmt>); * } * - * static int ftrace_reg_event_<call>(void) + * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused) * { * int ret; * @@ -366,7 +366,7 @@ static inline int ftrace_get_offsets_##call( \ * return ret; * } * - * static void ftrace_unreg_event_<call>(void) + * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) * { * unregister_trace_<call>(ftrace_event_<call>); * } @@ -399,7 +399,7 @@ static inline int ftrace_get_offsets_##call( \ * trace_current_buffer_unlock_commit(event, irq_flags, pc); * } * - * static int ftrace_raw_reg_event_<call>(void) + * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused) * { * int ret; * @@ -410,7 +410,7 @@ static inline int ftrace_get_offsets_##call( \ * return ret; * } * - * static void ftrace_unreg_event_<call>(void) + * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) * { * unregister_trace_<call>(ftrace_raw_event_<call>); * } @@ -419,7 +419,7 @@ static inline int ftrace_get_offsets_##call( \ * .trace = ftrace_raw_output_<call>, <-- stage 2 * }; * - * static int ftrace_raw_init_event_<call>(void) + * static int ftrace_raw_init_event_<call>(struct ftrace_event_call *unused) * { * int id; * @@ -537,7 +537,7 @@ static void ftrace_raw_event_##call(proto) \ trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \ } \ \ -static int ftrace_raw_reg_event_##call(void) \ +static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\ { \ int ret; \ \ @@ -548,7 +548,7 @@ static int ftrace_raw_reg_event_##call(void) \ return ret; \ } \ \ -static void ftrace_raw_unreg_event_##call(void) \ +static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\ { \ unregister_trace_##call(ftrace_raw_event_##call); \ } \ @@ -557,7 +557,7 @@ static struct trace_event ftrace_event_type_##call = { \ .trace = ftrace_raw_output_##call, \ }; \ \ -static int ftrace_raw_init_event_##call(void) \ +static int ftrace_raw_init_event_##call(struct ftrace_event_call *unused)\ { \ int id; \ \ diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 53c8fd3..94ff41e 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -60,9 +60,7 @@ err: } EXPORT_SYMBOL_GPL(trace_define_field); -#ifdef CONFIG_MODULES - -static void trace_destroy_fields(struct ftrace_event_call *call) +void trace_destroy_fields(struct ftrace_event_call *call) { struct ftrace_event_field *field, *next; @@ -74,8 +72,6 @@ static void trace_destroy_fields(struct ftrace_event_call *call) } } -#endif /* CONFIG_MODULES */ - static void ftrace_event_enable_disable(struct ftrace_event_call *call, int enable) { @@ -84,14 +80,14 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call, if (call->enabled) { call->enabled = 0; tracing_stop_cmdline_record(); - call->unregfunc(); + call->unregfunc(call); } break; case 1: if (!call->enabled) { call->enabled = 1; tracing_start_cmdline_record(); - call->regfunc(); + call->regfunc(call); } break; } @@ -574,7 +570,7 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt, trace_seq_printf(s, "format:\n"); trace_write_header(s); - r = call->show_format(s); + r = call->show_format(call, s); if (!r) { /* * ug! The format output is bigger than a PAGE!! @@ -921,7 +917,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, d_events = event_subsystem_dir(call->system, d_events); if (call->raw_init) { - ret = call->raw_init(); + ret = call->raw_init(call); if (ret < 0) { pr_warning("Could not initialize trace point" " events/%s\n", call->name); @@ -945,7 +941,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, id); if (call->define_fields) { - ret = call->define_fields(); + ret = call->define_fields(call); if (ret < 0) { pr_warning("Could not initialize trace point" " events/%s\n", call->name); @@ -965,6 +961,52 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, return 0; } +static int __trace_add_event_call(struct ftrace_event_call *call) +{ + struct dentry *d_events; + + if (!call->name) + return -EINVAL; + + d_events = event_trace_events_dir(); + if (!d_events) + return -ENOENT; + + list_add(&call->list, &ftrace_events); + return event_create_dir(call, d_events, &ftrace_event_id_fops, + &ftrace_enable_fops, &ftrace_event_filter_fops, + &ftrace_event_format_fops); +} + +/* Add an additional event_call dynamically */ +int trace_add_event_call(struct ftrace_event_call *call) +{ + int ret; + mutex_lock(&event_mutex); + ret = __trace_add_event_call(call); + mutex_unlock(&event_mutex); + return ret; +} + +static void __trace_remove_event_call(struct ftrace_event_call *call) +{ + ftrace_event_enable_disable(call, 0); + if (call->event) + __unregister_ftrace_event(call->event); + debugfs_remove_recursive(call->dir); + list_del(&call->list); + trace_destroy_fields(call); + destroy_preds(call); +} + +/* Remove an event_call */ +void trace_remove_event_call(struct ftrace_event_call *call) +{ + mutex_lock(&event_mutex); + __trace_remove_event_call(call); + mutex_unlock(&event_mutex); +} + #define for_each_event(event, start, end) \ for (event = start; \ (unsigned long)event < (unsigned long)end; \ @@ -1070,13 +1112,7 @@ static void trace_module_remove_events(struct module *mod) list_for_each_entry_safe(call, p, &ftrace_events, list) { if (call->mod == mod) { found = true; - ftrace_event_enable_disable(call, 0); - if (call->event) - __unregister_ftrace_event(call->event); - debugfs_remove_recursive(call->dir); - list_del(&call->list); - trace_destroy_fields(call); - destroy_preds(call); + __trace_remove_event_call(call); } } diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index d06cf89..7cee79d 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c @@ -60,7 +60,7 @@ extern void __bad_type_size(void); #undef TRACE_EVENT_FORMAT #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ static int \ -ftrace_format_##call(struct trace_seq *s) \ +ftrace_format_##call(struct ftrace_event_call *dummy, struct trace_seq *s)\ { \ struct args field; \ int ret; \ @@ -76,7 +76,7 @@ ftrace_format_##call(struct trace_seq *s) \ #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ tpfmt) \ static int \ -ftrace_format_##call(struct trace_seq *s) \ +ftrace_format_##call(struct ftrace_event_call *dummy, struct trace_seq *s)\ { \ struct args field; \ int ret; \ @@ -115,10 +115,16 @@ ftrace_format_##call(struct trace_seq *s) \ #define TRACE_FIELD_SPECIAL(type_item, item, len, cmd) \ cmd; +static int ftrace_raw_init_event(struct ftrace_event_call *event_call) +{ + INIT_LIST_HEAD(&event_call->fields); + init_preds(event_call); + return 0; +} + #undef TRACE_EVENT_FORMAT #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ -int ftrace_define_fields_##call(void); \ -static int ftrace_raw_init_event_##call(void); \ +int ftrace_define_fields_##call(struct ftrace_event_call *c); \ \ struct ftrace_event_call __used \ __attribute__((__aligned__(4))) \ @@ -126,16 +132,10 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ .name = #call, \ .id = proto, \ .system = __stringify(TRACE_SYSTEM), \ - .raw_init = ftrace_raw_init_event_##call, \ + .raw_init = ftrace_raw_init_event, \ .show_format = ftrace_format_##call, \ .define_fields = ftrace_define_fields_##call, \ -}; \ -static int ftrace_raw_init_event_##call(void) \ -{ \ - INIT_LIST_HEAD(&event_##call.fields); \ - init_preds(&event_##call); \ - return 0; \ -} \ +}; #undef TRACE_EVENT_FORMAT_NOFILTER #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, \ @@ -182,9 +182,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ #undef TRACE_EVENT_FORMAT #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ int \ -ftrace_define_fields_##call(void) \ +ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ { \ - struct ftrace_event_call *event_call = &event_##call; \ struct args field; \ int ret; \ \
Add dynamic ftrace_event_call support to ftrace. Trace engines can adds new ftrace_event_call to ftrace on the fly. Each operator functions of the call takes a ftrace_event_call data structure as an argument, because these functions may be shared among several ftrace_event_calls. Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Tom Zanussi <tzanussi@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> --- include/linux/ftrace_event.h | 13 +++++--- include/trace/ftrace.h | 22 +++++++------ kernel/trace/trace_events.c | 70 ++++++++++++++++++++++++++++++++---------- kernel/trace/trace_export.c | 27 ++++++++-------- 4 files changed, 85 insertions(+), 47 deletions(-)