Commit a1d0ce82 authored by Steven Rostedt's avatar Steven Rostedt Committed by Steven Rostedt

tracing: Use class->reg() for all registering of events

Because kprobes and syscalls need special processing to register
events, the class->reg() method was created to handle the differences.

But instead of creating a default ->reg for perf and ftrace events,
the code was scattered with:

	if (class->reg)
		class->reg();
	else
		default_reg();

This is messy and can also lead to bugs.

This patch cleans up this code and creates a default reg() entry for
the events allowing for the code to directly call the class->reg()
without the condition.
Reported-by: default avatarPeter Zijlstra <peterz@infradead.org>
Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent d62f85d1
...@@ -146,6 +146,9 @@ struct ftrace_event_class { ...@@ -146,6 +146,9 @@ struct ftrace_event_class {
int (*raw_init)(struct ftrace_event_call *); int (*raw_init)(struct ftrace_event_call *);
}; };
extern int ftrace_event_reg(struct ftrace_event_call *event,
enum trace_reg type);
enum { enum {
TRACE_EVENT_FL_ENABLED_BIT, TRACE_EVENT_FL_ENABLED_BIT,
TRACE_EVENT_FL_FILTERED_BIT, TRACE_EVENT_FL_FILTERED_BIT,
......
...@@ -439,6 +439,7 @@ static inline notrace int ftrace_get_offsets_##call( \ ...@@ -439,6 +439,7 @@ static inline notrace int ftrace_get_offsets_##call( \
* .fields = LIST_HEAD_INIT(event_class_##call.fields), * .fields = LIST_HEAD_INIT(event_class_##call.fields),
* .raw_init = trace_event_raw_init, * .raw_init = trace_event_raw_init,
* .probe = ftrace_raw_event_##call, * .probe = ftrace_raw_event_##call,
* .reg = ftrace_event_reg,
* }; * };
* *
* static struct ftrace_event_call __used * static struct ftrace_event_call __used
...@@ -567,6 +568,7 @@ static struct ftrace_event_class __used event_class_##call = { \ ...@@ -567,6 +568,7 @@ static struct ftrace_event_class __used event_class_##call = { \
.fields = LIST_HEAD_INIT(event_class_##call.fields),\ .fields = LIST_HEAD_INIT(event_class_##call.fields),\
.raw_init = trace_event_raw_init, \ .raw_init = trace_event_raw_init, \
.probe = ftrace_raw_event_##call, \ .probe = ftrace_raw_event_##call, \
.reg = ftrace_event_reg, \
_TRACE_PERF_INIT(call) \ _TRACE_PERF_INIT(call) \
}; };
......
...@@ -54,13 +54,7 @@ static int perf_trace_event_init(struct ftrace_event_call *tp_event, ...@@ -54,13 +54,7 @@ static int perf_trace_event_init(struct ftrace_event_call *tp_event,
} }
} }
if (tp_event->class->reg) ret = tp_event->class->reg(tp_event, TRACE_REG_PERF_REGISTER);
ret = tp_event->class->reg(tp_event, TRACE_REG_PERF_REGISTER);
else
ret = tracepoint_probe_register(tp_event->name,
tp_event->class->perf_probe,
tp_event);
if (ret) if (ret)
goto fail; goto fail;
...@@ -94,9 +88,7 @@ int perf_trace_init(struct perf_event *p_event) ...@@ -94,9 +88,7 @@ int perf_trace_init(struct perf_event *p_event)
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
list_for_each_entry(tp_event, &ftrace_events, list) { list_for_each_entry(tp_event, &ftrace_events, list) {
if (tp_event->event.type == event_id && if (tp_event->event.type == event_id &&
tp_event->class && tp_event->class && tp_event->class->reg &&
(tp_event->class->perf_probe ||
tp_event->class->reg) &&
try_module_get(tp_event->mod)) { try_module_get(tp_event->mod)) {
ret = perf_trace_event_init(tp_event, p_event); ret = perf_trace_event_init(tp_event, p_event);
break; break;
...@@ -136,12 +128,7 @@ void perf_trace_destroy(struct perf_event *p_event) ...@@ -136,12 +128,7 @@ void perf_trace_destroy(struct perf_event *p_event)
if (--tp_event->perf_refcount > 0) if (--tp_event->perf_refcount > 0)
goto out; goto out;
if (tp_event->class->reg) tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER);
tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER);
else
tracepoint_probe_unregister(tp_event->name,
tp_event->class->perf_probe,
tp_event);
/* /*
* Ensure our callback won't be called anymore. See * Ensure our callback won't be called anymore. See
......
...@@ -141,6 +141,35 @@ int trace_event_raw_init(struct ftrace_event_call *call) ...@@ -141,6 +141,35 @@ int trace_event_raw_init(struct ftrace_event_call *call)
} }
EXPORT_SYMBOL_GPL(trace_event_raw_init); EXPORT_SYMBOL_GPL(trace_event_raw_init);
int ftrace_event_reg(struct ftrace_event_call *call, enum trace_reg type)
{
switch (type) {
case TRACE_REG_REGISTER:
return tracepoint_probe_register(call->name,
call->class->probe,
call);
case TRACE_REG_UNREGISTER:
tracepoint_probe_unregister(call->name,
call->class->probe,
call);
return 0;
#ifdef CONFIG_PERF_EVENTS
case TRACE_REG_PERF_REGISTER:
return tracepoint_probe_register(call->name,
call->class->perf_probe,
call);
case TRACE_REG_PERF_UNREGISTER:
tracepoint_probe_unregister(call->name,
call->class->perf_probe,
call);
return 0;
#endif
}
return 0;
}
EXPORT_SYMBOL_GPL(ftrace_event_reg);
static int ftrace_event_enable_disable(struct ftrace_event_call *call, static int ftrace_event_enable_disable(struct ftrace_event_call *call,
int enable) int enable)
{ {
...@@ -151,23 +180,13 @@ static int ftrace_event_enable_disable(struct ftrace_event_call *call, ...@@ -151,23 +180,13 @@ static int ftrace_event_enable_disable(struct ftrace_event_call *call,
if (call->flags & TRACE_EVENT_FL_ENABLED) { if (call->flags & TRACE_EVENT_FL_ENABLED) {
call->flags &= ~TRACE_EVENT_FL_ENABLED; call->flags &= ~TRACE_EVENT_FL_ENABLED;
tracing_stop_cmdline_record(); tracing_stop_cmdline_record();
if (call->class->reg) call->class->reg(call, TRACE_REG_UNREGISTER);
call->class->reg(call, TRACE_REG_UNREGISTER);
else
tracepoint_probe_unregister(call->name,
call->class->probe,
call);
} }
break; break;
case 1: case 1:
if (!(call->flags & TRACE_EVENT_FL_ENABLED)) { if (!(call->flags & TRACE_EVENT_FL_ENABLED)) {
tracing_start_cmdline_record(); tracing_start_cmdline_record();
if (call->class->reg) ret = call->class->reg(call, TRACE_REG_REGISTER);
ret = call->class->reg(call, TRACE_REG_REGISTER);
else
ret = tracepoint_probe_register(call->name,
call->class->probe,
call);
if (ret) { if (ret) {
tracing_stop_cmdline_record(); tracing_stop_cmdline_record();
pr_info("event trace: Could not enable event " pr_info("event trace: Could not enable event "
...@@ -205,8 +224,7 @@ static int __ftrace_set_clr_event(const char *match, const char *sub, ...@@ -205,8 +224,7 @@ static int __ftrace_set_clr_event(const char *match, const char *sub,
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
list_for_each_entry(call, &ftrace_events, list) { list_for_each_entry(call, &ftrace_events, list) {
if (!call->name || !call->class || if (!call->name || !call->class || !call->class->reg)
(!call->class->probe && !call->class->reg))
continue; continue;
if (match && if (match &&
...@@ -332,7 +350,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos) ...@@ -332,7 +350,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
* The ftrace subsystem is for showing formats only. * The ftrace subsystem is for showing formats only.
* They can not be enabled or disabled via the event files. * They can not be enabled or disabled via the event files.
*/ */
if (call->class && (call->class->probe || call->class->reg)) if (call->class && call->class->reg)
return call; return call;
} }
...@@ -485,8 +503,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt, ...@@ -485,8 +503,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
list_for_each_entry(call, &ftrace_events, list) { list_for_each_entry(call, &ftrace_events, list) {
if (!call->name || !call->class || if (!call->name || !call->class || !call->class->reg)
(!call->class->probe && !call->class->reg))
continue; continue;
if (system && strcmp(call->class->system, system) != 0) if (system && strcmp(call->class->system, system) != 0)
...@@ -977,12 +994,12 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, ...@@ -977,12 +994,12 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
return -1; return -1;
} }
if (call->class->probe || call->class->reg) if (call->class->reg)
trace_create_file("enable", 0644, call->dir, call, trace_create_file("enable", 0644, call->dir, call,
enable); enable);
#ifdef CONFIG_PERF_EVENTS #ifdef CONFIG_PERF_EVENTS
if (call->event.type && (call->class->perf_probe || call->class->reg)) if (call->event.type && call->class->reg)
trace_create_file("id", 0444, call->dir, call, trace_create_file("id", 0444, call->dir, call,
id); id);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment