aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2008-12-02 23:50:02 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-03 02:56:23 -0500
commit14a866c567e040ccf6240d68b083dd1dbbde63e6 (patch)
tree4e8d62ecc345d44e7cd45f973ffb931070637532
parentbb4304c71c97bf727ec43cd2f195c2c237c27fd3 (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>
-rw-r--r--arch/x86/kernel/ftrace.c10
-rw-r--r--include/linux/ftrace.h2
-rw-r--r--kernel/trace/ftrace.c5
3 files changed, 13 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
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index afba918c623c..58ca1c3a3f4d 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -376,6 +376,8 @@ typedef void (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */
376extern int register_ftrace_graph(trace_func_graph_ret_t retfunc, 376extern int register_ftrace_graph(trace_func_graph_ret_t retfunc,
377 trace_func_graph_ent_t entryfunc); 377 trace_func_graph_ent_t entryfunc);
378 378
379extern void ftrace_graph_stop(void);
380
379/* The current handlers in use */ 381/* The current handlers in use */
380extern trace_func_graph_ret_t ftrace_graph_return; 382extern trace_func_graph_ret_t ftrace_graph_return;
381extern trace_func_graph_ent_t ftrace_graph_entry; 383extern trace_func_graph_ent_t ftrace_graph_entry;
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 2e78628443e8..a44af05ae2d0 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1769,5 +1769,10 @@ void ftrace_graph_exit_task(struct task_struct *t)
1769 1769
1770 kfree(ret_stack); 1770 kfree(ret_stack);
1771} 1771}
1772
1773void ftrace_graph_stop(void)
1774{
1775 ftrace_stop();
1776}
1772#endif 1777#endif
1773 1778