Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -146,6 +146,9 @@ struct ftrace_event_class {
	int			(*raw_init)(struct ftrace_event_call *);
};

extern int ftrace_event_reg(struct ftrace_event_call *event,
			    enum trace_reg type);

enum {
	TRACE_EVENT_FL_ENABLED_BIT,
	TRACE_EVENT_FL_FILTERED_BIT,
+2 −0
Original line number Diff line number Diff line
@@ -439,6 +439,7 @@ static inline notrace int ftrace_get_offsets_##call( \
 *	.fields			= LIST_HEAD_INIT(event_class_##call.fields),
 *	.raw_init		= trace_event_raw_init,
 *	.probe			= ftrace_raw_event_##call,
 *	.reg			= ftrace_event_reg,
 * };
 *
 * static struct ftrace_event_call __used
@@ -567,6 +568,7 @@ static struct ftrace_event_class __used event_class_##call = { \
	.fields			= LIST_HEAD_INIT(event_class_##call.fields),\
	.raw_init		= trace_event_raw_init,			\
	.probe			= ftrace_raw_event_##call,		\
	.reg			= ftrace_event_reg,			\
	_TRACE_PERF_INIT(call)						\
};

+3 −16
Original line number Diff line number Diff line
@@ -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);
	else
		ret = tracepoint_probe_register(tp_event->name,
						tp_event->class->perf_probe,
						tp_event);

	if (ret)
		goto fail;

@@ -94,9 +88,7 @@ int perf_trace_init(struct perf_event *p_event)
	mutex_lock(&event_mutex);
	list_for_each_entry(tp_event, &ftrace_events, list) {
		if (tp_event->event.type == event_id &&
		    tp_event->class &&
		    (tp_event->class->perf_probe ||
		     tp_event->class->reg) &&
		    tp_event->class && tp_event->class->reg &&
		    try_module_get(tp_event->mod)) {
			ret = perf_trace_event_init(tp_event, p_event);
			break;
@@ -136,12 +128,7 @@ void perf_trace_destroy(struct perf_event *p_event)
	if (--tp_event->perf_refcount > 0)
		goto out;

	if (tp_event->class->reg)
	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
+36 −19
Original line number Diff line number Diff line
@@ -141,6 +141,35 @@ int trace_event_raw_init(struct ftrace_event_call *call)
}
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,
					int enable)
{
@@ -151,23 +180,13 @@ static int ftrace_event_enable_disable(struct ftrace_event_call *call,
		if (call->flags & TRACE_EVENT_FL_ENABLED) {
			call->flags &= ~TRACE_EVENT_FL_ENABLED;
			tracing_stop_cmdline_record();
			if (call->class->reg)
			call->class->reg(call, TRACE_REG_UNREGISTER);
			else
				tracepoint_probe_unregister(call->name,
							    call->class->probe,
							    call);
		}
		break;
	case 1:
		if (!(call->flags & TRACE_EVENT_FL_ENABLED)) {
			tracing_start_cmdline_record();
			if (call->class->reg)
			ret = call->class->reg(call, TRACE_REG_REGISTER);
			else
				ret = tracepoint_probe_register(call->name,
								call->class->probe,
								call);
			if (ret) {
				tracing_stop_cmdline_record();
				pr_info("event trace: Could not enable event "
@@ -205,8 +224,7 @@ static int __ftrace_set_clr_event(const char *match, const char *sub,
	mutex_lock(&event_mutex);
	list_for_each_entry(call, &ftrace_events, list) {

		if (!call->name || !call->class ||
		    (!call->class->probe && !call->class->reg))
		if (!call->name || !call->class || !call->class->reg)
			continue;

		if (match &&
@@ -332,7 +350,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
		 * The ftrace subsystem is for showing formats only.
		 * 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;
	}

@@ -485,8 +503,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt,

	mutex_lock(&event_mutex);
	list_for_each_entry(call, &ftrace_events, list) {
		if (!call->name || !call->class ||
		    (!call->class->probe && !call->class->reg))
		if (!call->name || !call->class || !call->class->reg)
			continue;

		if (system && strcmp(call->class->system, system) != 0)
@@ -977,12 +994,12 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
		return -1;
	}

	if (call->class->probe || call->class->reg)
	if (call->class->reg)
		trace_create_file("enable", 0644, call->dir, call,
				  enable);

#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,
		 		  id);
#endif