Skip to content

Commit 8741db5

Browse files
Steven Rostedtrostedt
authored andcommitted
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 <[email protected]> Signed-off-by: Steven Rostedt <[email protected]>
1 parent 0f1ac8f commit 8741db5

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

kernel/trace/trace_functions_graph.c

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ struct fgraph_data {
4747
#define TRACE_GRAPH_PRINT_ABS_TIME 0x20
4848
#define TRACE_GRAPH_PRINT_IRQS 0x40
4949

50+
static unsigned int max_depth;
51+
5052
static struct tracer_opt trace_opts[] = {
5153
/* Display overruns? (for self-debug purpose) */
5254
{ TRACER_OPT(funcgraph-overrun, TRACE_GRAPH_PRINT_OVERRUN) },
@@ -250,8 +252,9 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
250252
return 0;
251253

252254
/* trace it when it is-nested-in or is a function enabled. */
253-
if (!(trace->depth || ftrace_graph_addr(trace->func)) ||
254-
ftrace_graph_ignore_irqs())
255+
if ((!(trace->depth || ftrace_graph_addr(trace->func)) ||
256+
ftrace_graph_ignore_irqs()) ||
257+
(max_depth && trace->depth >= max_depth))
255258
return 0;
256259

257260
local_irq_save(flags);
@@ -1457,6 +1460,59 @@ static struct tracer graph_trace __read_mostly = {
14571460
#endif
14581461
};
14591462

1463+
1464+
static ssize_t
1465+
graph_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+
1482+
static ssize_t
1483+
graph_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+
1494+
static 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+
1501+
static __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+
}
1514+
fs_initcall(init_graph_debugfs);
1515+
14601516
static __init int init_graph_trace(void)
14611517
{
14621518
max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1);

0 commit comments

Comments
 (0)