diff options
author | Steven Rostedt <srostedt@redhat.com> | 2008-12-02 23:50:02 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-03 02:56:23 -0500 |
commit | 14a866c567e040ccf6240d68b083dd1dbbde63e6 (patch) | |
tree | 4e8d62ecc345d44e7cd45f973ffb931070637532 /arch | |
parent | bb4304c71c97bf727ec43cd2f195c2c237c27fd3 (diff) |
ftrace: add ftrace_graph_stop()
Impact: new ftrace_graph_stop function
While developing more features of function graph, I hit a bug that
caused the WARN_ON to trigger in the prepare_ftrace_return function.
Well, it was hard for me to find out that was happening because the
bug would not print, it would just cause a hard lockup or reboot.
The reason is that it is not safe to call printk from this function.
Looking further, I also found that it calls unregister_ftrace_graph,
which grabs a mutex and calls kstop machine. This would definitely
lock the box up if it were to trigger.
This patch adds a fast and safe ftrace_graph_stop() which will
stop the function tracer. Then it is safe to call the WARN ON.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/ftrace.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 1a5b8f8cb3cc..adba8e9a427c 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -484,14 +484,16 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) | |||
484 | : "memory" | 484 | : "memory" |
485 | ); | 485 | ); |
486 | 486 | ||
487 | if (WARN_ON(faulted)) { | 487 | if (unlikely(faulted)) { |
488 | unregister_ftrace_graph(); | 488 | ftrace_graph_stop(); |
489 | WARN_ON(1); | ||
489 | return; | 490 | return; |
490 | } | 491 | } |
491 | 492 | ||
492 | if (WARN_ON(!__kernel_text_address(old))) { | 493 | if (unlikely(!__kernel_text_address(old))) { |
493 | unregister_ftrace_graph(); | 494 | ftrace_graph_stop(); |
494 | *parent = old; | 495 | *parent = old; |
496 | WARN_ON(1); | ||
495 | return; | 497 | return; |
496 | } | 498 | } |
497 | 499 | ||