aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ftrace.h2
-rw-r--r--kernel/sysctl.c10
-rw-r--r--kernel/trace/trace.c29
3 files changed, 38 insertions, 3 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index a3d46151be19..9623b7b9e5a5 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -165,6 +165,8 @@ static inline void __ftrace_enabled_restore(int enabled)
165#endif 165#endif
166 166
167#ifdef CONFIG_TRACING 167#ifdef CONFIG_TRACING
168extern int ftrace_dump_on_oops;
169
168extern void 170extern void
169ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); 171ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
170 172
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index a13bd4dfaeb1..84754f5801e6 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -484,6 +484,16 @@ static struct ctl_table kern_table[] = {
484 .proc_handler = &ftrace_enable_sysctl, 484 .proc_handler = &ftrace_enable_sysctl,
485 }, 485 },
486#endif 486#endif
487#ifdef CONFIG_TRACING
488 {
489 .ctl_name = CTL_UNNUMBERED,
490 .procname = "ftrace_dump_on_opps",
491 .data = &ftrace_dump_on_oops,
492 .maxlen = sizeof(int),
493 .mode = 0644,
494 .proc_handler = &proc_dointvec,
495 },
496#endif
487#ifdef CONFIG_MODULES 497#ifdef CONFIG_MODULES
488 { 498 {
489 .ctl_name = KERN_MODPROBE, 499 .ctl_name = KERN_MODPROBE,
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index d345d649d073..47f46cbdd860 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -63,6 +63,28 @@ static cpumask_t __read_mostly tracing_buffer_mask;
63 63
64static int tracing_disabled = 1; 64static int tracing_disabled = 1;
65 65
66/*
67 * ftrace_dump_on_oops - variable to dump ftrace buffer on oops
68 *
69 * If there is an oops (or kernel panic) and the ftrace_dump_on_oops
70 * is set, then ftrace_dump is called. This will output the contents
71 * of the ftrace buffers to the console. This is very useful for
72 * capturing traces that lead to crashes and outputing it to a
73 * serial console.
74 *
75 * It is default off, but you can enable it with either specifying
76 * "ftrace_dump_on_oops" in the kernel command line, or setting
77 * /proc/sys/kernel/ftrace_dump_on_oops to true.
78 */
79int ftrace_dump_on_oops;
80
81static int __init set_ftrace_dump_on_oops(char *str)
82{
83 ftrace_dump_on_oops = 1;
84 return 1;
85}
86__setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
87
66long 88long
67ns2usecs(cycle_t nsec) 89ns2usecs(cycle_t nsec)
68{ 90{
@@ -3021,7 +3043,8 @@ EXPORT_SYMBOL_GPL(__ftrace_printk);
3021static int trace_panic_handler(struct notifier_block *this, 3043static int trace_panic_handler(struct notifier_block *this,
3022 unsigned long event, void *unused) 3044 unsigned long event, void *unused)
3023{ 3045{
3024 ftrace_dump(); 3046 if (ftrace_dump_on_oops)
3047 ftrace_dump();
3025 return NOTIFY_OK; 3048 return NOTIFY_OK;
3026} 3049}
3027 3050
@@ -3037,7 +3060,8 @@ static int trace_die_handler(struct notifier_block *self,
3037{ 3060{
3038 switch (val) { 3061 switch (val) {
3039 case DIE_OOPS: 3062 case DIE_OOPS:
3040 ftrace_dump(); 3063 if (ftrace_dump_on_oops)
3064 ftrace_dump();
3041 break; 3065 break;
3042 default: 3066 default:
3043 break; 3067 break;
@@ -3078,7 +3102,6 @@ trace_printk_seq(struct trace_seq *s)
3078 trace_seq_reset(s); 3102 trace_seq_reset(s);
3079} 3103}
3080 3104
3081
3082void ftrace_dump(void) 3105void ftrace_dump(void)
3083{ 3106{
3084 static DEFINE_SPINLOCK(ftrace_dump_lock); 3107 static DEFINE_SPINLOCK(ftrace_dump_lock);