tracing: Make more function graph tracer options per-instance
cover tracing: Make more function graph tracer options per-instance
Convert the function graph tracer options sleep-time and funcgraph-irqs into per instance options (as they currently are not consistent in affecting all instances).
Also make graph-time a top level option only, as it only affects the function profiler and not the function graph tracer itself.
Clean up the function graph tracer set_flags() to use a switch instead of a bunch of if statements.
Steven Rostedt (4):
tracing: Have function graph tracer option funcgraph-irqs be per instance
tracing: Move graph-time out of function graph options
tracing: Have function graph tracer option sleep-time be per instance
tracing: Convert function graph set_flags() to use a switch() statement
----
kernel/trace/fgraph.c | 10 +-- kernel/trace/ftrace.c | 4 +- kernel/trace/trace.c | 14 +++-- kernel/trace/trace.h | 18 ++++-- kernel/trace/trace_functions_graph.c | 115 ++++++++++++++++++++++++++--------- 5 files changed, 115 insertions(+), 46 deletions(-)
PATCH 1/4 tracing: Have function graph tracer option funcgraph-irqs be per instance
From: Steven Rostedt <[email protected]>
Currently the option to trace interrupts in the function graph tracer is global when the interface is per-instance. Changing the value in one instance will affect the results of another instance that is also running the function graph tracer. This can lead to confusing results.
--- kernel/trace/trace_functions_graph.c | 41 +++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-)
kernel/trace/trace_functions_graph.c +31 -10
@@ -16,7 +16,7 @@#include "trace.h" #include "trace_output.h" -/* When set, irq functions will be ignored */ +/* When set, irq functions might be ignored */ static int ftrace_graph_skip_irqs;struct fgraph_cpu_data {
@@ -190,11 +190,14 @@ int __trace_graph_retaddr_entry(struct trace_array *tr, }#endif -static inline int ftrace_graph_ignore_irqs (void ) +static inline int ftrace_graph_ignore_irqs (struct trace_array *tr) {if (!ftrace_graph_skip_irqs ||trace_recursion_test (TRACE_IRQ_BIT ))return 0 ; +if (tracer_flags_is_set (tr,TRACE_GRAPH_PRINT_IRQS )) +return 0 ; +return in_hardirq (); }
@@ -238,7 +241,7 @@ static int graph_entry(struct ftrace_graph_ent *trace,if (ftrace_graph_ignore_func (gops, trace))return 0 ; -if (ftrace_graph_ignore_irqs ()) +if (ftrace_graph_ignore_irqs (tr))return 0 ;if (fgraph_sleep_time) {
@@ -451,6 +454,9 @@ static int graph_trace_init(struct trace_array *tr)else tr->gops->retfunc = trace_graph_return; +if (!tracer_flags_is_set (tr,TRACE_GRAPH_PRINT_IRQS )) + ftrace_graph_skip_irqs++; +/* Make gops functions visible before we start tracing */ smp_mb ();
@@ -468,10 +474,6 @@ static int ftrace_graph_trace_args(struct trace_array *tr, int set) {trace_func_graph_ent_t entry; -/* Do nothing if the current tracer is not this tracer */ -if (tr->current_trace != &graph_trace) -return 0 ; -if (set) entry = trace_graph_entry_args;else
@@ -492,6 +494,11 @@ static int ftrace_graph_trace_args(struct trace_array *tr, int set)static void graph_trace_reset (struct trace_array *tr) { +if (!tracer_flags_is_set (tr,TRACE_GRAPH_PRINT_IRQS )) + ftrace_graph_skip_irqs--; +if (WARN_ON_ONCE (ftrace_graph_skip_irqs <0 )) + ftrace_graph_skip_irqs =0 ; +tracing_stop_cmdline_record ();unregister_ftrace_graph (tr->gops); }
@@ -1617,15 +1624,29 @@ void graph_trace_close(struct trace_iterator *iter)static int 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); +/* Do nothing if the current tracer is not this tracer */ +if (tr->current_trace != &graph_trace) +return 0 ; + +/* Do nothing if already set. */ +if (!!set == !!(tr->current_trace_flags->val & bit)) +return 0 ; + +if (bit ==TRACE_GRAPH_PRINT_IRQS ) { +if (set) + ftrace_graph_skip_irqs--; +else + ftrace_graph_skip_irqs++; +if (WARN_ON_ONCE (ftrace_graph_skip_irqs <0 )) + ftrace_graph_skip_irqs =0 ; + } +if (bit ==TRACE_GRAPH_ARGS )return ftrace_graph_trace_args (tr, set);
Signature · 1 line
2.51.0
PATCH 2/4 tracing: Move graph-time out of function graph options
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The option "graph-time" affects the function profiler when it is using the function graph infrastructure. It has nothing to do with the function graph tracer itself. The option only affects the global function profiler and does nothing to the function graph tracer.
Move it out of the function graph tracer options and make it a global option that is only available at the top level instance.
--- kernel/trace/trace.c | 14 ++++++++++---- kernel/trace/trace.h | 13 ++++++++++++- kernel/trace/trace_functions_graph.c | 10 +--------- 3 files changed, 23 insertions(+), 14 deletions(-)
kernel/trace/trace.c +10 -4
@@ -509,10 +509,10 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_export);/* trace_flags holds trace_options default values */ #define TRACE_DEFAULT_FLAGS \ - (FUNCTION_DEFAULT_FLAGS | \ - TRACE_ITER(PRINT_PARENT) | TRACE_ITER(PRINTK) | \ + (FUNCTION_DEFAULT_FLAGS | FPROFILE_DEFAULT_FLAGS | \ + TRACE_ITER(PRINT_PARENT) | TRACE_ITER(PRINTK) | \ TRACE_ITER(ANNOTATE) | TRACE_ITER(CONTEXT_INFO) | \ - TRACE_ITER(RECORD_CMD) | TRACE_ITER(OVERWRITE) | \ + TRACE_ITER(RECORD_CMD) | TRACE_ITER(OVERWRITE) | \ TRACE_ITER(IRQ_INFO) | TRACE_ITER(MARKERS) | \ TRACE_ITER(HASH_PTR) | TRACE_ITER(TRACE_PRINTK) | \ TRACE_ITER(COPY_MARKER))
@@ -520,7 +520,7 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_export);/* trace_options that are only supported by global_trace */ #define TOP_LEVEL_TRACE_FLAGS (TRACE_ITER(PRINTK) | \ TRACE_ITER(PRINTK_MSGONLY) | TRACE_ITER(RECORD_CMD) | \ - TRACE_ITER(PROF_TEXT_OFFSET)) + TRACE_ITER(PROF_TEXT_OFFSET) | FPROFILE_DEFAULT_FLAGS)/* trace_flags that are default zero for instances */ #define ZEROED_TRACE_FLAGS \
@@ -5331,6 +5331,12 @@ int set_tracer_flag(struct trace_array *tr, u64 mask, int enabled)trace_printk_start_stop_comm (enabled);trace_printk_control (enabled);break ; + +#if defined(CONFIG_FUNCTION_PROFILER ) && defined(CONFIG_FUNCTION_GRAPH_TRACER ) +case TRACE_GRAPH_GRAPH_TIME : +ftrace_graph_graph_time_control (enabled); +break ; +#endif }return 0 ;
kernel/trace/trace.h +12 -1
@@ -1368,8 +1368,18 @@ extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,#ifdef CONFIG_FUNCTION_PROFILER # define PROFILER_FLAGS \ C(PROF_TEXT_OFFSET, "prof-text-offset"), +# ifdef CONFIG_FUNCTION_GRAPH_TRACER +# define FPROFILE_FLAGS \ + C(GRAPH_TIME, "graph-time"), +# define FPROFILE_DEFAULT_FLAGS TRACE_ITER(GRAPH_TIME) +# else +# define FPROFILE_FLAGS +# define FPROFILE_DEFAULT_FLAGS 0UL +# endif #else # define PROFILER_FLAGS +# define FPROFILE_FLAGS +# define FPROFILE_DEFAULT_FLAGS 0UL# define TRACE_ITER_PROF_TEXT_OFFSET_BIT -1#endif
@@ -1412,7 +1422,8 @@ extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,FGRAPH_FLAGS \ STACK_FLAGS \BRANCH_FLAGS \ -PROFILER_FLAGS + PROFILER_FLAGS \ +FPROFILE_FLAGS /* * By defining C, we can make TRACE_FLAGS a list of bit names
kernel/trace/trace_functions_graph.c +1 -9
@@ -85,11 +85,6 @@ static struct tracer_opt trace_opts[] = {/* Include sleep time (scheduled out) between entry and return */ { TRACER_OPT(sleep-time, TRACE_GRAPH_SLEEP_TIME) }, -#ifdef CONFIG_FUNCTION_PROFILER - /* Include time within nested functions */ - { TRACER_OPT(graph-time, TRACE_GRAPH_GRAPH_TIME) }, -#endif - { }/* Empty entry */ };
@@ -97,7 +92,7 @@ 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_SLEEP_TIME | TRACE_GRAPH_GRAPH_TIME, + TRACE_GRAPH_SLEEP_TIME, .opts = trace_opts };
@@ -1627,9 +1622,6 @@ func_graph_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int 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); -/* Do nothing if the current tracer is not this tracer */ if (tr->current_trace != &graph_trace)return 0 ;
Signature · 1 line
2.51.0
PATCH 3/4 tracing: Have function graph tracer option sleep-time be per instance
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Currently the option to have function graph tracer to ignore time spent when a task is sleeping is global when the interface is per-instance. Changing the value in one instance will affect the results of another instance that is also running the function graph tracer. This can lead to confusing results.
--- kernel/trace/fgraph.c | 10 +---- kernel/trace/ftrace.c | 4 +- kernel/trace/trace.h | 5 +-- kernel/trace/trace_functions_graph.c | 64 +++++++++++++++++++++++----- 4 files changed, 60 insertions(+), 23 deletions(-)
kernel/trace/fgraph.c +1 -9
@@ -498,9 +498,6 @@ void *fgraph_retrieve_parent_data(int idx, int *size_bytes, int depth)return get_data_type_data (current, offset); } -/* Both enabled by default (can be cleared by function_graph tracer flags */ -bool fgraph_sleep_time = true; -#ifdef CONFIG_DYNAMIC_FTRACE /* * archs can override this function if they must do something
@@ -1023,11 +1020,6 @@ void fgraph_init_ops(struct ftrace_ops *dst_ops,#endif } -void ftrace_graph_sleep_time_control (bool enable) -{ - fgraph_sleep_time = enable; -} -/* * Simply points to ftrace_stub, but with the proper protocol. * Defined by the linker script in linux/vmlinux.lds.h
@@ -1098,7 +1090,7 @@ ftrace_graph_probe_sched_switch(void *ignore, bool preempt,* Does the user want to count the time a function was asleep. * If so, do not update the time stamps. */ -if (fgraph_sleep_time) +if (!fgraph_no_sleep_time)return ; timestamp =trace_clock_local ();
kernel/trace/ftrace.c +3 -1
@@ -862,6 +862,8 @@ static int profile_graph_entry(struct ftrace_graph_ent *trace,return 1 ; } +bool fprofile_no_sleep_time; +static void profile_graph_return (struct ftrace_graph_ret *trace,struct fgraph_ops *gops,struct ftrace_regs *fregs)
@@ -887,7 +889,7 @@ static void profile_graph_return(struct ftrace_graph_ret *trace, calltime = rettime - profile_data->calltime; -if (!fgraph_sleep_time) { +if (fprofile_no_sleep_time) {if (current->ftrace_sleeptime) calltime -= current->ftrace_sleeptime - profile_data->sleeptime; }
kernel/trace/trace.h +2 -3
@@ -943,8 +943,6 @@ static __always_inline bool ftrace_hash_empty(struct ftrace_hash *hash)#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); -#ifdef CONFIG_FUNCTION_PROFILER extern void ftrace_graph_graph_time_control (bool enable);#else
@@ -1115,7 +1113,8 @@ static inline void ftrace_graph_addr_finish(struct fgraph_ops *gops, struct ftra#endif /* CONFIG_DYNAMIC_FTRACE */ extern unsigned int fgraph_max_depth; -extern bool fgraph_sleep_time; +extern unsigned int fgraph_no_sleep_time; +extern bool fprofile_no_sleep_time;static inline bool ftrace_graph_ignore_func (struct fgraph_ops *gops,struct ftrace_graph_ent *trace)
kernel/trace/trace_functions_graph.c +54 -10
130 lines not on this page · raw message
Signature · 1 line
2.51.0
PATCH 4/4 tracing: Convert function graph set_flags() to use a switch() statement
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Currently the set_flags() of the function graph tracer has a bunch of:
if (bit == FLAG1) {
[..]}
if (bit == FLAG2) {
[..]}
To clean it up a bit, convert it over to a switch statement.
--- kernel/trace/trace_functions_graph.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
kernel/trace/trace_functions_graph.c +7 -5
@@ -1664,7 +1664,8 @@ func_graph_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)if (!!set == !!(tr->current_trace_flags->val & bit))return 0 ; -if (bit ==TRACE_GRAPH_SLEEP_TIME ) { +switch (bit) { +case TRACE_GRAPH_SLEEP_TIME :if (set) { fgraph_no_sleep_time--;if (WARN_ON_ONCE (fgraph_no_sleep_time <0 ))
@@ -1672,19 +1673,20 @@ func_graph_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set) }else { fgraph_no_sleep_time++; } - } +break ; -if (bit ==TRACE_GRAPH_PRINT_IRQS ) { +case TRACE_GRAPH_PRINT_IRQS :if (set) ftrace_graph_skip_irqs--;else ftrace_graph_skip_irqs++;if (WARN_ON_ONCE (ftrace_graph_skip_irqs <0 )) ftrace_graph_skip_irqs =0 ; - } +break ; -if (bit ==TRACE_GRAPH_ARGS ) +case TRACE_GRAPH_ARGS :return ftrace_graph_trace_args (tr, set); + }return 0 ; }
Signature · 1 line
2.51.0