|
@@ -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");
|