aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2008-12-16 23:06:40 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-18 06:56:24 -0500
commitf38f1d2aa5a3520cf05da7cd6bd12fe2b0c509b7 (patch)
tree5eef795a1a081c41686971eaaa5ba2d1098ceb9d
parent40874491f9e9a4cb08eaf663dbe018bf5671975a (diff)
trace: add a way to enable or disable the stack tracer
Impact: enhancement to stack tracer The stack tracer currently is either on when configured in or off when it is not. It can not be disabled when it is configured on. (besides disabling the function tracer that it uses) This patch adds a way to enable or disable the stack tracer at run time. It defaults off on bootup, but a kernel parameter 'stacktrace' has been added to enable it on bootup. A new sysctl has been added "kernel.stack_tracer_enabled" to let the user enable or disable the stack tracer at run time. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--include/linux/ftrace.h8
-rw-r--r--kernel/sysctl.c10
-rw-r--r--kernel/trace/Kconfig13
-rw-r--r--kernel/trace/trace_stack.c52
5 files changed, 79 insertions, 8 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 2919a2e9193..edab81c1318 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -89,6 +89,7 @@ parameter is applicable:
89 SPARC Sparc architecture is enabled. 89 SPARC Sparc architecture is enabled.
90 SWSUSP Software suspend (hibernation) is enabled. 90 SWSUSP Software suspend (hibernation) is enabled.
91 SUSPEND System suspend states are enabled. 91 SUSPEND System suspend states are enabled.
92 FTRACE Function tracing enabled.
92 TS Appropriate touchscreen support is enabled. 93 TS Appropriate touchscreen support is enabled.
93 USB USB support is enabled. 94 USB USB support is enabled.
94 USBHID USB Human Interface Device support is enabled. 95 USBHID USB Human Interface Device support is enabled.
@@ -2173,6 +2174,9 @@ and is between 256 and 4096 characters. It is defined in the file
2173 st= [HW,SCSI] SCSI tape parameters (buffers, etc.) 2174 st= [HW,SCSI] SCSI tape parameters (buffers, etc.)
2174 See Documentation/scsi/st.txt. 2175 See Documentation/scsi/st.txt.
2175 2176
2177 stacktrace [FTRACE]
2178 Enabled the stack tracer on boot up.
2179
2176 sti= [PARISC,HW] 2180 sti= [PARISC,HW]
2177 Format: <num> 2181 Format: <num>
2178 Set the STI (builtin display/keyboard on the HP-PARISC 2182 Set the STI (builtin display/keyboard on the HP-PARISC
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 44020f31bd8..6b0db53caa7 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -86,6 +86,14 @@ static inline void ftrace_stop(void) { }
86static inline void ftrace_start(void) { } 86static inline void ftrace_start(void) { }
87#endif /* CONFIG_FUNCTION_TRACER */ 87#endif /* CONFIG_FUNCTION_TRACER */
88 88
89#ifdef CONFIG_STACK_TRACER
90extern int stack_tracer_enabled;
91int
92stack_trace_sysctl(struct ctl_table *table, int write,
93 struct file *file, void __user *buffer, size_t *lenp,
94 loff_t *ppos);
95#endif
96
89#ifdef CONFIG_DYNAMIC_FTRACE 97#ifdef CONFIG_DYNAMIC_FTRACE
90/* asm/ftrace.h must be defined for archs supporting dynamic ftrace */ 98/* asm/ftrace.h must be defined for archs supporting dynamic ftrace */
91#include <asm/ftrace.h> 99#include <asm/ftrace.h>
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c83f566e940..6ac501a2dcc 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -487,6 +487,16 @@ static struct ctl_table kern_table[] = {
487 .proc_handler = &ftrace_enable_sysctl, 487 .proc_handler = &ftrace_enable_sysctl,
488 }, 488 },
489#endif 489#endif
490#ifdef CONFIG_STACK_TRACER
491 {
492 .ctl_name = CTL_UNNUMBERED,
493 .procname = "stack_tracer_enabled",
494 .data = &stack_tracer_enabled,
495 .maxlen = sizeof(int),
496 .mode = 0644,
497 .proc_handler = &stack_trace_sysctl,
498 },
499#endif
490#ifdef CONFIG_TRACING 500#ifdef CONFIG_TRACING
491 { 501 {
492 .ctl_name = CTL_UNNUMBERED, 502 .ctl_name = CTL_UNNUMBERED,
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index d8bae6f4219..e2a4ff6fc3a 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -244,10 +244,15 @@ config STACK_TRACER
244 244
245 This tracer works by hooking into every function call that the 245 This tracer works by hooking into every function call that the
246 kernel executes, and keeping a maximum stack depth value and 246 kernel executes, and keeping a maximum stack depth value and
247 stack-trace saved. Because this logic has to execute in every 247 stack-trace saved. If this is configured with DYNAMIC_FTRACE
248 kernel function, all the time, this option can slow down the 248 then it will not have any overhead while the stack tracer
249 kernel measurably and is generally intended for kernel 249 is disabled.
250 developers only. 250
251 To enable the stack tracer on bootup, pass in 'stacktrace'
252 on the kernel command line.
253
254 The stack tracer can also be enabled or disabled via the
255 sysctl kernel.stack_tracer_enabled
251 256
252 Say N if unsure. 257 Say N if unsure.
253 258
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 0b863f2cbc8..4842c969c78 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -10,6 +10,7 @@
10#include <linux/debugfs.h> 10#include <linux/debugfs.h>
11#include <linux/ftrace.h> 11#include <linux/ftrace.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/sysctl.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/fs.h> 15#include <linux/fs.h>
15#include "trace.h" 16#include "trace.h"
@@ -31,6 +32,10 @@ static raw_spinlock_t max_stack_lock =
31 32
32static int stack_trace_disabled __read_mostly; 33static int stack_trace_disabled __read_mostly;
33static DEFINE_PER_CPU(int, trace_active); 34static DEFINE_PER_CPU(int, trace_active);
35static DEFINE_MUTEX(stack_sysctl_mutex);
36
37int stack_tracer_enabled;
38static int last_stack_tracer_enabled;
34 39
35static inline void check_stack(void) 40static inline void check_stack(void)
36{ 41{
@@ -174,7 +179,7 @@ stack_max_size_write(struct file *filp, const char __user *ubuf,
174 return count; 179 return count;
175} 180}
176 181
177static struct file_operations stack_max_size_fops = { 182static const struct file_operations stack_max_size_fops = {
178 .open = tracing_open_generic, 183 .open = tracing_open_generic,
179 .read = stack_max_size_read, 184 .read = stack_max_size_read,
180 .write = stack_max_size_write, 185 .write = stack_max_size_write,
@@ -272,7 +277,7 @@ static int t_show(struct seq_file *m, void *v)
272 return 0; 277 return 0;
273} 278}
274 279
275static struct seq_operations stack_trace_seq_ops = { 280static const struct seq_operations stack_trace_seq_ops = {
276 .start = t_start, 281 .start = t_start,
277 .next = t_next, 282 .next = t_next,
278 .stop = t_stop, 283 .stop = t_stop,
@@ -288,12 +293,48 @@ static int stack_trace_open(struct inode *inode, struct file *file)
288 return ret; 293 return ret;
289} 294}
290 295
291static struct file_operations stack_trace_fops = { 296static const struct file_operations stack_trace_fops = {
292 .open = stack_trace_open, 297 .open = stack_trace_open,
293 .read = seq_read, 298 .read = seq_read,
294 .llseek = seq_lseek, 299 .llseek = seq_lseek,
295}; 300};
296 301
302int
303stack_trace_sysctl(struct ctl_table *table, int write,
304 struct file *file, void __user *buffer, size_t *lenp,
305 loff_t *ppos)
306{
307 int ret;
308
309 mutex_lock(&stack_sysctl_mutex);
310
311 ret = proc_dointvec(table, write, file, buffer, lenp, ppos);
312
313 if (ret || !write ||
314 (last_stack_tracer_enabled == stack_tracer_enabled))
315 goto out;
316
317 last_stack_tracer_enabled = stack_tracer_enabled;
318
319 if (stack_tracer_enabled)
320 register_ftrace_function(&trace_ops);
321 else
322 unregister_ftrace_function(&trace_ops);
323
324 out:
325 mutex_unlock(&stack_sysctl_mutex);
326 return ret;
327}
328
329static int start_stack_trace __initdata;
330
331static __init int enable_stacktrace(char *str)
332{
333 start_stack_trace = 1;
334 return 1;
335}
336__setup("stacktrace", enable_stacktrace);
337
297static __init int stack_trace_init(void) 338static __init int stack_trace_init(void)
298{ 339{
299 struct dentry *d_tracer; 340 struct dentry *d_tracer;
@@ -311,7 +352,10 @@ static __init int stack_trace_init(void)
311 if (!entry) 352 if (!entry)
312 pr_warning("Could not create debugfs 'stack_trace' entry\n"); 353 pr_warning("Could not create debugfs 'stack_trace' entry\n");
313 354
314 register_ftrace_function(&trace_ops); 355 if (start_stack_trace) {
356 register_ftrace_function(&trace_ops);
357 stack_tracer_enabled = 1;
358 }
315 359
316 return 0; 360 return 0;
317} 361}