diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2009-09-14 16:48:56 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-09-16 22:03:40 -0400 |
commit | 2d5e067edc4635ff7515bfa9ab3edb38bc344cab (patch) | |
tree | 6c266b7d5a0013c73d729d83e0ae6b3458d0b125 /kernel/trace/trace_kprobe.c | |
parent | f52487e9c0041842eeb77c6c48774414b1cede08 (diff) |
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: 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>
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r-- | kernel/trace/trace_kprobe.c | 42 |
1 files changed, 19 insertions, 23 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index cbc0870dcf5d..ea0db8eee570 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -347,20 +347,15 @@ static struct trace_probe *find_probe_event(const char *event) | |||
347 | return NULL; | 347 | return NULL; |
348 | } | 348 | } |
349 | 349 | ||
350 | static void __unregister_trace_probe(struct trace_probe *tp) | 350 | /* Unregister a trace_probe and probe_event: call with locking probe_lock */ |
351 | static void unregister_trace_probe(struct trace_probe *tp) | ||
351 | { | 352 | { |
352 | if (probe_is_return(tp)) | 353 | if (probe_is_return(tp)) |
353 | unregister_kretprobe(&tp->rp); | 354 | unregister_kretprobe(&tp->rp); |
354 | else | 355 | else |
355 | unregister_kprobe(&tp->rp.kp); | 356 | unregister_kprobe(&tp->rp.kp); |
356 | } | ||
357 | |||
358 | /* Unregister a trace_probe and probe_event: call with locking probe_lock */ | ||
359 | static void unregister_trace_probe(struct trace_probe *tp) | ||
360 | { | ||
361 | unregister_probe_event(tp); | ||
362 | __unregister_trace_probe(tp); | ||
363 | list_del(&tp->list); | 357 | list_del(&tp->list); |
358 | unregister_probe_event(tp); | ||
364 | } | 359 | } |
365 | 360 | ||
366 | /* Register a trace_probe and probe_event */ | 361 | /* Register a trace_probe and probe_event */ |
@@ -371,6 +366,19 @@ static int register_trace_probe(struct trace_probe *tp) | |||
371 | 366 | ||
372 | mutex_lock(&probe_lock); | 367 | mutex_lock(&probe_lock); |
373 | 368 | ||
369 | /* register as an event */ | ||
370 | old_tp = find_probe_event(tp->call.name); | ||
371 | if (old_tp) { | ||
372 | /* delete old event */ | ||
373 | unregister_trace_probe(old_tp); | ||
374 | free_trace_probe(old_tp); | ||
375 | } | ||
376 | ret = register_probe_event(tp); | ||
377 | if (ret) { | ||
378 | pr_warning("Faild to register probe event(%d)\n", ret); | ||
379 | goto end; | ||
380 | } | ||
381 | |||
374 | if (probe_is_return(tp)) | 382 | if (probe_is_return(tp)) |
375 | ret = register_kretprobe(&tp->rp); | 383 | ret = register_kretprobe(&tp->rp); |
376 | else | 384 | else |
@@ -384,21 +392,9 @@ static int register_trace_probe(struct trace_probe *tp) | |||
384 | tp->rp.kp.addr); | 392 | tp->rp.kp.addr); |
385 | ret = -EINVAL; | 393 | ret = -EINVAL; |
386 | } | 394 | } |
387 | goto end; | 395 | unregister_probe_event(tp); |
388 | } | 396 | } else |
389 | /* register as an event */ | 397 | list_add_tail(&tp->list, &probe_list); |
390 | old_tp = find_probe_event(tp->call.name); | ||
391 | if (old_tp) { | ||
392 | /* delete old event */ | ||
393 | unregister_trace_probe(old_tp); | ||
394 | free_trace_probe(old_tp); | ||
395 | } | ||
396 | ret = register_probe_event(tp); | ||
397 | if (ret) { | ||
398 | pr_warning("Faild to register probe event(%d)\n", ret); | ||
399 | __unregister_trace_probe(tp); | ||
400 | } | ||
401 | list_add_tail(&tp->list, &probe_list); | ||
402 | end: | 398 | end: |
403 | mutex_unlock(&probe_lock); | 399 | mutex_unlock(&probe_lock); |
404 | return ret; | 400 | return ret; |