|
@@ -262,6 +262,35 @@ int trace_graph_thresh_entry(struct ftrace_graph_ent *trace)
|
|
return trace_graph_entry(trace);
|
|
return trace_graph_entry(trace);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void
|
|
|
|
+__trace_graph_function(struct trace_array *tr,
|
|
|
|
+ unsigned long ip, unsigned long flags, int pc)
|
|
|
|
+{
|
|
|
|
+ u64 time = trace_clock_local();
|
|
|
|
+ struct ftrace_graph_ent ent = {
|
|
|
|
+ .func = ip,
|
|
|
|
+ .depth = 0,
|
|
|
|
+ };
|
|
|
|
+ struct ftrace_graph_ret ret = {
|
|
|
|
+ .func = ip,
|
|
|
|
+ .depth = 0,
|
|
|
|
+ .calltime = time,
|
|
|
|
+ .rettime = time,
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ __trace_graph_entry(tr, &ent, flags, pc);
|
|
|
|
+ __trace_graph_return(tr, &ret, flags, pc);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+trace_graph_function(struct trace_array *tr,
|
|
|
|
+ unsigned long ip, unsigned long parent_ip,
|
|
|
|
+ unsigned long flags, int pc)
|
|
|
|
+{
|
|
|
|
+ __trace_graph_function(tr, parent_ip, flags, pc);
|
|
|
|
+ __trace_graph_function(tr, ip, flags, pc);
|
|
|
|
+}
|
|
|
|
+
|
|
void __trace_graph_return(struct trace_array *tr,
|
|
void __trace_graph_return(struct trace_array *tr,
|
|
struct ftrace_graph_ret *trace,
|
|
struct ftrace_graph_ret *trace,
|
|
unsigned long flags,
|
|
unsigned long flags,
|
|
@@ -1179,7 +1208,7 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
|
|
|
|
|
|
|
|
|
|
enum print_line_t
|
|
enum print_line_t
|
|
-print_graph_function_flags(struct trace_iterator *iter, u32 flags)
|
|
|
|
|
|
+__print_graph_function_flags(struct trace_iterator *iter, u32 flags)
|
|
{
|
|
{
|
|
struct ftrace_graph_ent_entry *field;
|
|
struct ftrace_graph_ent_entry *field;
|
|
struct fgraph_data *data = iter->private;
|
|
struct fgraph_data *data = iter->private;
|
|
@@ -1242,7 +1271,18 @@ print_graph_function_flags(struct trace_iterator *iter, u32 flags)
|
|
static enum print_line_t
|
|
static enum print_line_t
|
|
print_graph_function(struct trace_iterator *iter)
|
|
print_graph_function(struct trace_iterator *iter)
|
|
{
|
|
{
|
|
- return print_graph_function_flags(iter, tracer_flags.val);
|
|
|
|
|
|
+ return __print_graph_function_flags(iter, tracer_flags.val);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+enum print_line_t print_graph_function_flags(struct trace_iterator *iter,
|
|
|
|
+ u32 flags)
|
|
|
|
+{
|
|
|
|
+ if (trace_flags & TRACE_ITER_LATENCY_FMT)
|
|
|
|
+ flags |= TRACE_GRAPH_PRINT_DURATION;
|
|
|
|
+ else
|
|
|
|
+ flags |= TRACE_GRAPH_PRINT_ABS_TIME;
|
|
|
|
+
|
|
|
|
+ return __print_graph_function_flags(iter, flags);
|
|
}
|
|
}
|
|
|
|
|
|
static enum print_line_t
|
|
static enum print_line_t
|
|
@@ -1274,7 +1314,7 @@ static void print_lat_header(struct seq_file *s, u32 flags)
|
|
seq_printf(s, "#%.*s|||| / \n", size, spaces);
|
|
seq_printf(s, "#%.*s|||| / \n", size, spaces);
|
|
}
|
|
}
|
|
|
|
|
|
-void print_graph_headers_flags(struct seq_file *s, u32 flags)
|
|
|
|
|
|
+static void __print_graph_headers_flags(struct seq_file *s, u32 flags)
|
|
{
|
|
{
|
|
int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
|
|
int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
|
|
|
|
|
|
@@ -1315,6 +1355,23 @@ void print_graph_headers(struct seq_file *s)
|
|
print_graph_headers_flags(s, tracer_flags.val);
|
|
print_graph_headers_flags(s, tracer_flags.val);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void print_graph_headers_flags(struct seq_file *s, u32 flags)
|
|
|
|
+{
|
|
|
|
+ struct trace_iterator *iter = s->private;
|
|
|
|
+
|
|
|
|
+ if (trace_flags & TRACE_ITER_LATENCY_FMT) {
|
|
|
|
+ /* print nothing if the buffers are empty */
|
|
|
|
+ if (trace_empty(iter))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ print_trace_header(s, iter);
|
|
|
|
+ flags |= TRACE_GRAPH_PRINT_DURATION;
|
|
|
|
+ } else
|
|
|
|
+ flags |= TRACE_GRAPH_PRINT_ABS_TIME;
|
|
|
|
+
|
|
|
|
+ __print_graph_headers_flags(s, flags);
|
|
|
|
+}
|
|
|
|
+
|
|
void graph_trace_open(struct trace_iterator *iter)
|
|
void graph_trace_open(struct trace_iterator *iter)
|
|
{
|
|
{
|
|
/* pid and depth on the last trace processed */
|
|
/* pid and depth on the last trace processed */
|