aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_functions_graph.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2013-01-16 10:49:37 -0500
committerSteven Rostedt <rostedt@goodmis.org>2013-01-21 13:22:34 -0500
commit8741db532e86da2e54f05be751bfe1922ca63d57 (patch)
treec2687a6151b869d562e729f58651a32da5436518 /kernel/trace/trace_functions_graph.c
parent0f1ac8fd254b6c3e77950a1c4ee67be5dc88f7e0 (diff)
tracing/fgraph: Add max_graph_depth to limit function_graph depth
Add the file max_graph_depth to the debug tracing directory that lets the user define the depth of the function graph. A very useful operation is to set the depth to 1. Then it traces only the first function that is called when entering the kernel. This can be used to determine what system operations interrupt a process. For example, to work on NOHZ processes (single tasks running without a timer tick), if any interrupt goes off and preempts that task, this code will show it happening. # cd /sys/kernel/debug/tracing # echo 1 > max_graph_depth # echo function_graph > current_tracer # cat per_cpu/cpu/<cpu-of-process>/trace Cc: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_functions_graph.c')
-rw-r--r--kernel/trace/trace_functions_graph.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 4edb4b74eb7e..7008d2e13cf2 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -47,6 +47,8 @@ struct fgraph_data {
47#define TRACE_GRAPH_PRINT_ABS_TIME 0x20 47#define TRACE_GRAPH_PRINT_ABS_TIME 0x20
48#define TRACE_GRAPH_PRINT_IRQS 0x40 48#define TRACE_GRAPH_PRINT_IRQS 0x40
49 49
50static unsigned int max_depth;
51
50static struct tracer_opt trace_opts[] = { 52static struct tracer_opt trace_opts[] = {
51 /* Display overruns? (for self-debug purpose) */ 53 /* Display overruns? (for self-debug purpose) */
52 { TRACER_OPT(funcgraph-overrun, TRACE_GRAPH_PRINT_OVERRUN) }, 54 { TRACER_OPT(funcgraph-overrun, TRACE_GRAPH_PRINT_OVERRUN) },
@@ -250,8 +252,9 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
250 return 0; 252 return 0;
251 253
252 /* trace it when it is-nested-in or is a function enabled. */ 254 /* trace it when it is-nested-in or is a function enabled. */
253 if (!(trace->depth || ftrace_graph_addr(trace->func)) || 255 if ((!(trace->depth || ftrace_graph_addr(trace->func)) ||
254 ftrace_graph_ignore_irqs()) 256 ftrace_graph_ignore_irqs()) ||
257 (max_depth && trace->depth >= max_depth))
255 return 0; 258 return 0;
256 259
257 local_irq_save(flags); 260 local_irq_save(flags);
@@ -1457,6 +1460,59 @@ static struct tracer graph_trace __read_mostly = {
1457#endif 1460#endif
1458}; 1461};
1459 1462
1463
1464static ssize_t
1465graph_depth_write(struct file *filp, const char __user *ubuf, size_t cnt,
1466 loff_t *ppos)
1467{
1468 unsigned long val;
1469 int ret;
1470
1471 ret = kstrtoul_from_user(ubuf, cnt, 10, &val);
1472 if (ret)
1473 return ret;
1474
1475 max_depth = val;
1476
1477 *ppos += cnt;
1478
1479 return cnt;
1480}
1481
1482static ssize_t
1483graph_depth_read(struct file *filp, char __user *ubuf, size_t cnt,
1484 loff_t *ppos)
1485{
1486 char buf[15]; /* More than enough to hold UINT_MAX + "\n"*/
1487 int n;
1488
1489 n = sprintf(buf, "%d\n", max_depth);
1490
1491 return simple_read_from_buffer(ubuf, cnt, ppos, buf, n);
1492}
1493
1494static const struct file_operations graph_depth_fops = {
1495 .open = tracing_open_generic,
1496 .write = graph_depth_write,
1497 .read = graph_depth_read,
1498 .llseek = generic_file_llseek,
1499};
1500
1501static __init int init_graph_debugfs(void)
1502{
1503 struct dentry *d_tracer;
1504
1505 d_tracer = tracing_init_dentry();
1506 if (!d_tracer)
1507 return 0;
1508
1509 trace_create_file("max_graph_depth", 0644, d_tracer,
1510 NULL, &graph_depth_fops);
1511
1512 return 0;
1513}
1514fs_initcall(init_graph_debugfs);
1515
1460static __init int init_graph_trace(void) 1516static __init int init_graph_trace(void)
1461{ 1517{
1462 max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1); 1518 max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1);