summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/ftrace.c19
-rw-r--r--kernel/trace/trace.c2
-rw-r--r--kernel/trace/trace.h11
-rw-r--r--kernel/trace/trace_functions_graph.c13
4 files changed, 35 insertions, 10 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index b0623ac..e763848 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -243,6 +243,11 @@ static void ftrace_sync_ipi(void *data)
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
static void update_function_graph_func(void);
+
+/* Both enabled by default (can be cleared by function_graph tracer flags */
+static bool fgraph_sleep_time = true;
+static bool fgraph_graph_time = true;
+
#else
static inline void update_function_graph_func(void) { }
#endif
@@ -917,7 +922,7 @@ static void profile_graph_return(struct ftrace_graph_ret *trace)
calltime = trace->rettime - trace->calltime;
- if (!(trace_flags & TRACE_ITER_GRAPH_TIME)) {
+ if (!fgraph_graph_time) {
int index;
index = trace->depth;
@@ -5639,6 +5644,16 @@ static struct ftrace_ops graph_ops = {
ASSIGN_OPS_HASH(graph_ops, &global_ops.local_hash)
};
+void ftrace_graph_sleep_time_control(bool enable)
+{
+ fgraph_sleep_time = enable;
+}
+
+void ftrace_graph_graph_time_control(bool enable)
+{
+ fgraph_graph_time = enable;
+}
+
int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
{
return 0;
@@ -5707,7 +5722,7 @@ ftrace_graph_probe_sched_switch(void *ignore,
* Does the user want to count the time a function was asleep.
* If so, do not update the time stamps.
*/
- if (trace_flags & TRACE_ITER_SLEEP_TIME)
+ if (fgraph_sleep_time)
return;
timestamp = trace_clock_local();
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index d98789b..e26933c 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -492,7 +492,7 @@ static inline void ftrace_trace_stack(struct ring_buffer *buffer,
/* trace_flags holds trace_options default values */
unsigned long trace_flags =
- FUNCTION_DEFAULT_FLAGS | FUNCTION_GRAPH_DEFAULT_FLAGS |
+ FUNCTION_DEFAULT_FLAGS |
TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO |
TRACE_ITER_RECORD_CMD | TRACE_ITER_OVERWRITE |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 33d1e53..5219bf5 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -714,9 +714,14 @@ extern char trace_find_mark(unsigned long long duration);
#define TRACE_GRAPH_PRINT_ABS_TIME 0x20
#define TRACE_GRAPH_PRINT_IRQS 0x40
#define TRACE_GRAPH_PRINT_TAIL 0x80
+#define TRACE_GRAPH_SLEEP_TIME 0x100
+#define TRACE_GRAPH_GRAPH_TIME 0x200
#define TRACE_GRAPH_PRINT_FILL_SHIFT 28
#define TRACE_GRAPH_PRINT_FILL_MASK (0x3 << TRACE_GRAPH_PRINT_FILL_SHIFT)
+extern void ftrace_graph_sleep_time_control(bool enable);
+extern void ftrace_graph_graph_time_control(bool enable);
+
extern enum print_line_t
print_graph_function_flags(struct trace_iterator *iter, u32 flags);
extern void print_graph_headers_flags(struct seq_file *s, u32 flags);
@@ -892,15 +897,9 @@ extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
*/
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
# define FGRAPH_FLAGS \
- C(SLEEP_TIME, "sleep-time"), \
- C(GRAPH_TIME, "graph-time"), \
C(DISPLAY_GRAPH, "display-graph"),
-/* Initially set for trace_flags */
-# define FUNCTION_GRAPH_DEFAULT_FLAGS \
- (TRACE_ITER_SLEEP_TIME | TRACE_ITER_GRAPH_TIME)
#else
# define FGRAPH_FLAGS
-# define FUNCTION_GRAPH_DEFAULT_FLAGS 0UL
#endif
#ifdef CONFIG_BRANCH_TRACER
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index ca98445..86e45c2 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -83,13 +83,18 @@ static struct tracer_opt trace_opts[] = {
{ TRACER_OPT(funcgraph-irqs, TRACE_GRAPH_PRINT_IRQS) },
/* Display function name after trailing } */
{ TRACER_OPT(funcgraph-tail, TRACE_GRAPH_PRINT_TAIL) },
+ /* Include sleep time (scheduled out) between entry and return */
+ { TRACER_OPT(sleep-time, TRACE_GRAPH_SLEEP_TIME) },
+ /* Include time within nested functions */
+ { TRACER_OPT(graph-time, TRACE_GRAPH_GRAPH_TIME) },
{ } /* Empty entry */
};
static struct tracer_flags tracer_flags = {
/* Don't display overruns, proc, or tail by default */
.val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD |
- TRACE_GRAPH_PRINT_DURATION | TRACE_GRAPH_PRINT_IRQS,
+ TRACE_GRAPH_PRINT_DURATION | TRACE_GRAPH_PRINT_IRQS |
+ TRACE_GRAPH_SLEEP_TIME | TRACE_GRAPH_GRAPH_TIME,
.opts = trace_opts
};
@@ -1362,6 +1367,12 @@ func_graph_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)
if (bit == TRACE_GRAPH_PRINT_IRQS)
ftrace_graph_skip_irqs = !set;
+ if (bit == TRACE_GRAPH_SLEEP_TIME)
+ ftrace_graph_sleep_time_control(set);
+
+ if (bit == TRACE_GRAPH_GRAPH_TIME)
+ ftrace_graph_graph_time_control(set);
+
return 0;
}