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

Commit 2d5e067e authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Frederic Weisbecker
Browse files

tracing/kprobes: Fix trace_probe registration order



Fix trace_probe registration order. ftrace_event_call and ftrace_event
must be registered before kprobe/kretprobe, because tracing/profiling
handlers dereference the event-id.

Signed-off-by: default avatarMasami Hiramatsu <mhiramat@redhat.com>
Acked-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jason Baron <jbaron@redhat.com>
Cc: K.Prasad <prasad@linux.vnet.ibm.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <20090914204856.18779.52961.stgit@dhcp-100-2-132.bos.redhat.com>
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
parent f52487e9
Loading
Loading
Loading
Loading
+19 −23
Original line number Diff line number Diff line
@@ -347,20 +347,15 @@ static struct trace_probe *find_probe_event(const char *event)
	return NULL;
}

static void __unregister_trace_probe(struct trace_probe *tp)
/* Unregister a trace_probe and probe_event: call with locking probe_lock */
static void unregister_trace_probe(struct trace_probe *tp)
{
	if (probe_is_return(tp))
		unregister_kretprobe(&tp->rp);
	else
		unregister_kprobe(&tp->rp.kp);
}

/* Unregister a trace_probe and probe_event: call with locking probe_lock */
static void unregister_trace_probe(struct trace_probe *tp)
{
	unregister_probe_event(tp);
	__unregister_trace_probe(tp);
	list_del(&tp->list);
	unregister_probe_event(tp);
}

/* Register a trace_probe and probe_event */
@@ -371,6 +366,19 @@ static int register_trace_probe(struct trace_probe *tp)

	mutex_lock(&probe_lock);

	/* register as an event */
	old_tp = find_probe_event(tp->call.name);
	if (old_tp) {
		/* delete old event */
		unregister_trace_probe(old_tp);
		free_trace_probe(old_tp);
	}
	ret = register_probe_event(tp);
	if (ret) {
		pr_warning("Faild to register probe event(%d)\n", ret);
		goto end;
	}

	if (probe_is_return(tp))
		ret = register_kretprobe(&tp->rp);
	else
@@ -384,20 +392,8 @@ static int register_trace_probe(struct trace_probe *tp)
				   tp->rp.kp.addr);
			ret = -EINVAL;
		}
		goto end;
	}
	/* register as an event */
	old_tp = find_probe_event(tp->call.name);
	if (old_tp) {
		/* delete old event */
		unregister_trace_probe(old_tp);
		free_trace_probe(old_tp);
	}
	ret = register_probe_event(tp);
	if (ret) {
		pr_warning("Faild to register probe event(%d)\n", ret);
		__unregister_trace_probe(tp);
	}
		unregister_probe_event(tp);
	} else
		list_add_tail(&tp->list, &probe_list);
end:
	mutex_unlock(&probe_lock);