tracing/kprobes: Fix trace_probe registration order
authorMasami Hiramatsu <mhiramat@redhat.com>
Mon, 14 Sep 2009 20:48:56 +0000 (16:48 -0400)
committerFrederic Weisbecker <fweisbec@gmail.com>
Thu, 17 Sep 2009 02:03:40 +0000 (04:03 +0200)
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: Masami Hiramatsu <mhiramat@redhat.com>
Acked-by: Steven 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: Frederic Weisbecker <fweisbec@gmail.com>
kernel/trace/trace_kprobe.c

index cbc0870..ea0db8e 100644 (file)
@@ -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,21 +392,9 @@ 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);
-       }
-       list_add_tail(&tp->list, &probe_list);
+               unregister_probe_event(tp);
+       } else
+               list_add_tail(&tp->list, &probe_list);
 end:
        mutex_unlock(&probe_lock);
        return ret;