SPARC   Sparc architecture is enabled.
        SWSUSP  Software suspend (hibernation) is enabled.
        SUSPEND System suspend states are enabled.
+       FTRACE  Function tracing enabled.
        TS      Appropriate touchscreen support is enabled.
        USB     USB support is enabled.
        USBHID  USB Human Interface Device support is enabled.
        st=             [HW,SCSI] SCSI tape parameters (buffers, etc.)
                        See Documentation/scsi/st.txt.
 
+       stacktrace      [FTRACE]
+                       Enabled the stack tracer on boot up.
+
        sti=            [PARISC,HW]
                        Format: <num>
                        Set the STI (builtin display/keyboard on the HP-PARISC
 
 static inline void ftrace_start(void) { }
 #endif /* CONFIG_FUNCTION_TRACER */
 
+#ifdef CONFIG_STACK_TRACER
+extern int stack_tracer_enabled;
+int
+stack_trace_sysctl(struct ctl_table *table, int write,
+                  struct file *file, void __user *buffer, size_t *lenp,
+                  loff_t *ppos);
+#endif
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 /* asm/ftrace.h must be defined for archs supporting dynamic ftrace */
 #include <asm/ftrace.h>
 
                .proc_handler   = &ftrace_enable_sysctl,
        },
 #endif
+#ifdef CONFIG_STACK_TRACER
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "stack_tracer_enabled",
+               .data           = &stack_tracer_enabled,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &stack_trace_sysctl,
+       },
+#endif
 #ifdef CONFIG_TRACING
        {
                .ctl_name       = CTL_UNNUMBERED,
 
 
          This tracer works by hooking into every function call that the
          kernel executes, and keeping a maximum stack depth value and
-         stack-trace saved. Because this logic has to execute in every
-         kernel function, all the time, this option can slow down the
-         kernel measurably and is generally intended for kernel
-         developers only.
+         stack-trace saved.  If this is configured with DYNAMIC_FTRACE
+         then it will not have any overhead while the stack tracer
+         is disabled.
+
+         To enable the stack tracer on bootup, pass in 'stacktrace'
+         on the kernel command line.
+
+         The stack tracer can also be enabled or disabled via the
+         sysctl kernel.stack_tracer_enabled
 
          Say N if unsure.
 
 
 #include <linux/debugfs.h>
 #include <linux/ftrace.h>
 #include <linux/module.h>
+#include <linux/sysctl.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include "trace.h"
 
 static int stack_trace_disabled __read_mostly;
 static DEFINE_PER_CPU(int, trace_active);
+static DEFINE_MUTEX(stack_sysctl_mutex);
+
+int stack_tracer_enabled;
+static int last_stack_tracer_enabled;
 
 static inline void check_stack(void)
 {
        return count;
 }
 
-static struct file_operations stack_max_size_fops = {
+static const struct file_operations stack_max_size_fops = {
        .open           = tracing_open_generic,
        .read           = stack_max_size_read,
        .write          = stack_max_size_write,
        return 0;
 }
 
-static struct seq_operations stack_trace_seq_ops = {
+static const struct seq_operations stack_trace_seq_ops = {
        .start          = t_start,
        .next           = t_next,
        .stop           = t_stop,
        return ret;
 }
 
-static struct file_operations stack_trace_fops = {
+static const struct file_operations stack_trace_fops = {
        .open           = stack_trace_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
 };
 
+int
+stack_trace_sysctl(struct ctl_table *table, int write,
+                  struct file *file, void __user *buffer, size_t *lenp,
+                  loff_t *ppos)
+{
+       int ret;
+
+       mutex_lock(&stack_sysctl_mutex);
+
+       ret  = proc_dointvec(table, write, file, buffer, lenp, ppos);
+
+       if (ret || !write ||
+           (last_stack_tracer_enabled == stack_tracer_enabled))
+               goto out;
+
+       last_stack_tracer_enabled = stack_tracer_enabled;
+
+       if (stack_tracer_enabled)
+               register_ftrace_function(&trace_ops);
+       else
+               unregister_ftrace_function(&trace_ops);
+
+ out:
+       mutex_unlock(&stack_sysctl_mutex);
+       return ret;
+}
+
+static int start_stack_trace __initdata;
+
+static __init int enable_stacktrace(char *str)
+{
+       start_stack_trace = 1;
+       return 1;
+}
+__setup("stacktrace", enable_stacktrace);
+
 static __init int stack_trace_init(void)
 {
        struct dentry *d_tracer;
        if (!entry)
                pr_warning("Could not create debugfs 'stack_trace' entry\n");
 
-       register_ftrace_function(&trace_ops);
+       if (start_stack_trace) {
+               register_ftrace_function(&trace_ops);
+               stack_tracer_enabled = 1;
+       }
 
        return 0;
 }