tracing: add latency format to function_graph tracer
While debugging something with the function_graph tracer, I found the need to see the preempt count of the traces. Unfortunately, since the function graph tracer has its own output formatting, it does not honor the latency-format option. This patch makes the function_graph tracer honor the latency-format option, but still keeps control of the output. But now we have the same details that the latency-format supplies. # tracer: function_graph # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / # |||| # CPU|||| DURATION FUNCTION CALLS # | |||| | | | | | | 3) d..1 1.333 us | idle_cpu(); 3) d.h1 | tick_check_idle() { 3) d.h1 0.550 us | tick_check_oneshot_broadcast(); 3) d.h1 | tick_nohz_stop_idle() { 3) d.h1 | ktime_get() { 3) d.h1 | ktime_get_ts() { Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
parent
fc06b8520b
commit
49ff590390
|
@ -364,6 +364,29 @@ print_graph_proc(struct trace_seq *s, pid_t pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static enum print_line_t
|
||||||
|
print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
|
||||||
|
{
|
||||||
|
int hardirq, softirq;
|
||||||
|
|
||||||
|
hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
|
||||||
|
softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
|
||||||
|
|
||||||
|
if (!trace_seq_printf(s, " %c%c%c",
|
||||||
|
(entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
|
||||||
|
(entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
|
||||||
|
'X' : '.',
|
||||||
|
(entry->flags & TRACE_FLAG_NEED_RESCHED) ?
|
||||||
|
'N' : '.',
|
||||||
|
(hardirq && softirq) ? 'H' :
|
||||||
|
hardirq ? 'h' : softirq ? 's' : '.'))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (entry->preempt_count)
|
||||||
|
return trace_seq_printf(s, "%x", entry->preempt_count);
|
||||||
|
return trace_seq_puts(s, ".");
|
||||||
|
}
|
||||||
|
|
||||||
/* If the pid changed since the last trace, output this event */
|
/* If the pid changed since the last trace, output this event */
|
||||||
static enum print_line_t
|
static enum print_line_t
|
||||||
verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data)
|
verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data)
|
||||||
|
@ -521,6 +544,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
|
||||||
if (ret == TRACE_TYPE_PARTIAL_LINE)
|
if (ret == TRACE_TYPE_PARTIAL_LINE)
|
||||||
return TRACE_TYPE_PARTIAL_LINE;
|
return TRACE_TYPE_PARTIAL_LINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Proc */
|
/* Proc */
|
||||||
if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
|
||||||
ret = print_graph_proc(s, pid);
|
ret = print_graph_proc(s, pid);
|
||||||
|
@ -758,6 +782,13 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
|
||||||
return TRACE_TYPE_PARTIAL_LINE;
|
return TRACE_TYPE_PARTIAL_LINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Latency format */
|
||||||
|
if (trace_flags & TRACE_ITER_LATENCY_FMT) {
|
||||||
|
ret = print_graph_lat_fmt(s, ent);
|
||||||
|
if (ret == TRACE_TYPE_PARTIAL_LINE)
|
||||||
|
return TRACE_TYPE_PARTIAL_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,28 +983,59 @@ print_graph_function(struct trace_iterator *iter)
|
||||||
return TRACE_TYPE_HANDLED;
|
return TRACE_TYPE_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_lat_header(struct seq_file *s)
|
||||||
|
{
|
||||||
|
static const char spaces[] = " " /* 16 spaces */
|
||||||
|
" " /* 4 spaces */
|
||||||
|
" "; /* 17 spaces */
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
|
||||||
|
size += 16;
|
||||||
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
|
||||||
|
size += 4;
|
||||||
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
|
||||||
|
size += 17;
|
||||||
|
|
||||||
|
seq_printf(s, "#%.*s _-----=> irqs-off \n", size, spaces);
|
||||||
|
seq_printf(s, "#%.*s / _----=> need-resched \n", size, spaces);
|
||||||
|
seq_printf(s, "#%.*s| / _---=> hardirq/softirq \n", size, spaces);
|
||||||
|
seq_printf(s, "#%.*s|| / _--=> preempt-depth \n", size, spaces);
|
||||||
|
seq_printf(s, "#%.*s||| / \n", size, spaces);
|
||||||
|
seq_printf(s, "#%.*s|||| \n", size, spaces);
|
||||||
|
}
|
||||||
|
|
||||||
static void print_graph_headers(struct seq_file *s)
|
static void print_graph_headers(struct seq_file *s)
|
||||||
{
|
{
|
||||||
|
int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
|
||||||
|
|
||||||
|
if (lat)
|
||||||
|
print_lat_header(s);
|
||||||
|
|
||||||
/* 1st line */
|
/* 1st line */
|
||||||
seq_printf(s, "# ");
|
seq_printf(s, "#");
|
||||||
if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
|
||||||
seq_printf(s, " TIME ");
|
seq_printf(s, " TIME ");
|
||||||
if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
|
||||||
seq_printf(s, "CPU");
|
seq_printf(s, " CPU");
|
||||||
if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
|
||||||
seq_printf(s, " TASK/PID ");
|
seq_printf(s, " TASK/PID ");
|
||||||
|
if (lat)
|
||||||
|
seq_printf(s, "||||");
|
||||||
if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
|
||||||
seq_printf(s, " DURATION ");
|
seq_printf(s, " DURATION ");
|
||||||
seq_printf(s, " FUNCTION CALLS\n");
|
seq_printf(s, " FUNCTION CALLS\n");
|
||||||
|
|
||||||
/* 2nd line */
|
/* 2nd line */
|
||||||
seq_printf(s, "# ");
|
seq_printf(s, "#");
|
||||||
if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
|
||||||
seq_printf(s, " | ");
|
seq_printf(s, " | ");
|
||||||
if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
|
||||||
seq_printf(s, "| ");
|
seq_printf(s, " | ");
|
||||||
if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
|
||||||
seq_printf(s, " | | ");
|
seq_printf(s, " | | ");
|
||||||
|
if (lat)
|
||||||
|
seq_printf(s, "||||");
|
||||||
if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
|
if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
|
||||||
seq_printf(s, " | | ");
|
seq_printf(s, " | | ");
|
||||||
seq_printf(s, " | | | |\n");
|
seq_printf(s, " | | | |\n");
|
||||||
|
|
Loading…
Reference in a new issue