tracing: Mulitple tracers and other updates
Subsystems (4)
Steven Rostedt
maintainercover tracing: Mulitple tracers and other updates
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
for-next
Head SHA1: ad1438a076e275b70d1a04de1364bc483e5a81db
Fabian Frederick (1):
tracing: Add static to local functions
Mathias Krause (1):
ftrace: Statically initialize pm notifier block
Petr Mladek (1):
ftrace/x86: Fix order of warning messages when ftrace modifies code
Steven Rostedt (Red Hat) (5):
ftrace: Remove global function list and call function directly
tracing: Move tracing_max_latency into trace_array
tracing: Move ftrace_max_lock into trace_array
tracing: Allow wakeup tracers to be used by instances
tracing: Allow irq/preempt tracers to be used by instances
----
arch/x86/kernel/ftrace.c | 2 +- include/linux/ftrace.h | 20 ++--- kernel/trace/ftrace.c | 158 +++++++++++--------------------------- kernel/trace/trace.c | 60 ++++++--------- kernel/trace/trace.h | 36 ++++++--- kernel/trace/trace_functions.c | 55 +++++-------- kernel/trace/trace_irqsoff.c | 71 +++++++++-------- kernel/trace/trace_sched_wakeup.c | 68 +++++++++------- kernel/trace/trace_selftest.c | 69 +++++++++-------- 9 files changed, 239 insertions(+), 300 deletions(-)
Steven Rostedt
maintainerPATCH 1/8 ftrace: Remove global function list and call function directly
From: "Steven Rostedt (Red Hat)" <[email protected]>
Instead of having a list of global functions that are called, as only one global function is allow to be enabled at a time, there's no reason to have a list.
Instead, simply have all the users of the global ops, use the global ops directly, instead of registering their own ftrace_ops. Just switch what function is used before enabling the function tracer.
This removes a lot of code as well as the complexity involved with it.
--- include/linux/ftrace.h | 20 ++--- kernel/trace/ftrace.c | 152 +++++++++++--------------------------- kernel/trace/trace.c | 2 + kernel/trace/trace.h | 19 +++-- kernel/trace/trace_functions.c | 55 +++++--------- kernel/trace/trace_irqsoff.c | 33 ++++----- kernel/trace/trace_sched_wakeup.c | 40 +++++----- kernel/trace/trace_selftest.c | 33 +++++---- 8 files changed, 133 insertions(+), 221 deletions(-)
include/linux/ftrace.h +8 -12
@@ -62,9 +62,6 @@ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip,* set in the flags member. * * ENABLED - set/unset when ftrace_ops is registered/unregistered -* GLOBAL - set manualy by ftrace_ops user to denote the ftrace_ops -* is part of the global tracers sharing the same filter -* via set_ftrace_* debugfs files. * DYNAMIC - set when ftrace_ops is registered to denote dynamically * allocated ftrace_ops which need special care * CONTROL - set manualy by ftrace_ops user to denote the ftrace_ops
@@ -96,15 +93,14 @@ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip,*/ enum {FTRACE_OPS_FL_ENABLED =1 <<0 , -FTRACE_OPS_FL_GLOBAL =1 <<1 , -FTRACE_OPS_FL_DYNAMIC =1 <<2 , -FTRACE_OPS_FL_CONTROL =1 <<3 , -FTRACE_OPS_FL_SAVE_REGS =1 <<4 , -FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED =1 <<5 , -FTRACE_OPS_FL_RECURSION_SAFE =1 <<6 , -FTRACE_OPS_FL_STUB =1 <<7 , -FTRACE_OPS_FL_INITIALIZED =1 <<8 , -FTRACE_OPS_FL_DELETED =1 <<9 , +FTRACE_OPS_FL_DYNAMIC =1 <<1 , +FTRACE_OPS_FL_CONTROL =1 <<2 , +FTRACE_OPS_FL_SAVE_REGS =1 <<3 , +FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED =1 <<4 , +FTRACE_OPS_FL_RECURSION_SAFE =1 <<5 , +FTRACE_OPS_FL_STUB =1 <<6 , +FTRACE_OPS_FL_INITIALIZED =1 <<7 , +FTRACE_OPS_FL_DELETED =1 <<8 , };/*
kernel/trace/ftrace.c +42 -110
250 lines not on this page · raw message
kernel/trace/trace.c +2 -0
@@ -6629,6 +6629,8 @@ __init static int tracer_alloc_buffers(void)*/ global_trace.current_trace = &nop_trace; +ftrace_init_global_array_ops (&global_trace); +register_tracer (&nop_trace);/* All seems OK, enable tracing */
kernel/trace/trace.h +9 -10
@@ -416,13 +416,7 @@ enum {TRACE_FTRACE_IRQ_BIT ,TRACE_FTRACE_SIRQ_BIT , -/* GLOBAL_BITs must be greater than FTRACE_BITs */ -TRACE_GLOBAL_BIT , -TRACE_GLOBAL_NMI_BIT , -TRACE_GLOBAL_IRQ_BIT , -TRACE_GLOBAL_SIRQ_BIT , - -/* INTERNAL_BITs must be greater than GLOBAL_BITs */ +/* INTERNAL_BITs must be greater than FTRACE_BITs */ TRACE_INTERNAL_BIT ,TRACE_INTERNAL_NMI_BIT , TRACE_INTERNAL_IRQ_BIT,
@@ -449,9 +443,6 @@ enum {#define TRACE_FTRACE_START TRACE_FTRACE_BIT#define TRACE_FTRACE_MAX ((1 << (TRACE_FTRACE_START + TRACE_CONTEXT_BITS)) - 1) -#define TRACE_GLOBAL_START TRACE_GLOBAL_BIT -#define TRACE_GLOBAL_MAX ((1 << (TRACE_GLOBAL_START + TRACE_CONTEXT_BITS)) - 1) -#define TRACE_LIST_START TRACE_INTERNAL_BIT#define TRACE_LIST_MAX ((1 << (TRACE_LIST_START + TRACE_CONTEXT_BITS)) - 1)
@@ -823,6 +814,9 @@ extern int ftrace_is_dead(void);int ftrace_create_function_files (struct trace_array *tr,struct dentry *parent);void ftrace_destroy_function_files (struct trace_array *tr); +void ftrace_init_global_array_ops (struct trace_array *tr); +void ftrace_init_array_ops (struct trace_array *tr,ftrace_func_t func); +void ftrace_reset_array_ops (struct trace_array *tr);#else static inline int ftrace_trace_task (struct task_struct *task) {
@@ -836,6 +830,11 @@ ftrace_create_function_files(struct trace_array *tr, return 0; }static inline void ftrace_destroy_function_files (struct trace_array *tr) { } +static inline __init void +ftrace_init_global_array_ops (struct trace_array *tr) { } +static inline void ftrace_reset_array_ops (struct trace_array *tr) { } +/* ftace_func_t type is not defined, use macro instead of static inline */ +#define ftrace_init_array_ops (tr, func) do { } while (0)#endif /* CONFIG_FUNCTION_TRACER */ #if defined(CONFIG_FUNCTION_TRACER ) && defined(CONFIG_DYNAMIC_FTRACE )
kernel/trace/trace_functions.c +19 -36
89 lines not on this page · raw message
kernel/trace/trace_irqsoff.c +16 -17
@@ -151,12 +151,6 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip, atomic_dec(&data->disabled); } - -static struct ftrace_ops trace_ops__read_mostly = -{ - .func = irqsoff_tracer_call, - .flags =FTRACE_OPS_FL_GLOBAL |FTRACE_OPS_FL_RECURSION_SAFE , -};#endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@ -531,7 +525,7 @@ void trace_preempt_off(unsigned long a0, unsigned long a1) }#endif /* CONFIG_PREEMPT_TRACER */ -static int register_irqsoff_function (int graph,int set) +static int register_irqsoff_function (struct trace_array *tr,int graph,int set) {int ret;
@@ -543,7 +537,7 @@ static int register_irqsoff_function(int graph, int set) ret =register_ftrace_graph (&irqsoff_graph_return, &irqsoff_graph_entry); else - ret =register_ftrace_function (&trace_ops); + ret =register_ftrace_function (tr->ops);if (!ret) function_enabled = true;
@@ -551,7 +545,7 @@ static int register_irqsoff_function(int graph, int set)return ret; } -static void unregister_irqsoff_function (int graph) +static void unregister_irqsoff_function (struct trace_array *tr,int graph) {if (!function_enabled)return ;
@@ -559,17 +553,17 @@ static void unregister_irqsoff_function(int graph)if (graph)unregister_ftrace_graph ();else -unregister_ftrace_function (&trace_ops); +unregister_ftrace_function (tr->ops); function_enabled = false; } -static void irqsoff_function_set (int set) +static void irqsoff_function_set (struct trace_array *tr,int set) {if (set) -register_irqsoff_function (is_graph (),1 ); +register_irqsoff_function (tr,is_graph (),1 );else -unregister_irqsoff_function (is_graph ()); +unregister_irqsoff_function (tr,is_graph ()); }static int irqsoff_flag_changed (struct trace_array *tr,u32 mask,int set)
@@ -577,7 +571,7 @@ static int irqsoff_flag_changed(struct trace_array *tr, u32 mask, int set)struct tracer *tracer = tr->current_trace;if (mask &TRACE_ITER_FUNCTION ) -irqsoff_function_set (set); +irqsoff_function_set (tr, set);return trace_keep_overwrite (tracer, mask, set); }
@@ -586,7 +580,7 @@ static int start_irqsoff_tracer(struct trace_array *tr, int graph) {int ret; - ret =register_irqsoff_function (graph,0 ); + ret =register_irqsoff_function (tr, graph,0 );if (!ret &&tracing_is_enabled ()) tracer_enabled =1 ;
@@ -600,7 +594,7 @@ static void stop_irqsoff_tracer(struct trace_array *tr, int graph) { tracer_enabled =0 ; -unregister_irqsoff_function (graph); +unregister_irqsoff_function (tr, graph); }static void __irqsoff_tracer_init (struct trace_array *tr)
@@ -617,7 +611,11 @@ static void __irqsoff_tracer_init(struct trace_array *tr)smp_wmb ();tracing_reset_online_cpus (&tr->trace_buffer); -if (start_irqsoff_tracer (tr,is_graph ())) +ftrace_init_array_ops (tr, irqsoff_tracer_call); + +/* Only toplevel instance supports graph tracing */ +if (start_irqsoff_tracer (tr, (tr->flags &TRACE_ARRAY_FL_GLOBAL && +is_graph ())))printk (KERN_ERR "failed to start irqsoff tracer\n" ); }
@@ -630,6 +628,7 @@ static void irqsoff_tracer_reset(struct trace_array *tr)set_tracer_flag (tr,TRACE_ITER_LATENCY_FMT , lat_flag);set_tracer_flag (tr,TRACE_ITER_OVERWRITE , overwrite_flag); +ftrace_reset_array_ops (tr); }static void irqsoff_tracer_start (struct trace_array *tr)
kernel/trace/trace_sched_wakeup.c +18 -22
@@ -130,15 +130,9 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip,atomic_dec (&data->disabled); preempt_enable_notrace(); } - -static struct ftrace_ops trace_ops__read_mostly = -{ - .func = wakeup_tracer_call, - .flags =FTRACE_OPS_FL_GLOBAL |FTRACE_OPS_FL_RECURSION_SAFE , -};#endif /* CONFIG_FUNCTION_TRACER */ -static int register_wakeup_function (int graph,int set) +static int register_wakeup_function (struct trace_array *tr,int graph,int set) {int ret;
@@ -150,7 +144,7 @@ static int register_wakeup_function(int graph, int set) ret =register_ftrace_graph (&wakeup_graph_return, &wakeup_graph_entry); else - ret =register_ftrace_function (&trace_ops); + ret =register_ftrace_function (tr->ops);if (!ret) function_enabled = true;
@@ -158,7 +152,7 @@ static int register_wakeup_function(int graph, int set)return ret; } -static void unregister_wakeup_function (int graph) +static void unregister_wakeup_function (struct trace_array *tr,int graph) {if (!function_enabled)return ;
@@ -166,17 +160,17 @@ static void unregister_wakeup_function(int graph)if (graph)unregister_ftrace_graph ();else -unregister_ftrace_function (&trace_ops); +unregister_ftrace_function (tr->ops); function_enabled = false; } -static void wakeup_function_set (int set) +static void wakeup_function_set (struct trace_array *tr,int set) {if (set) -register_wakeup_function (is_graph (),1 ); +register_wakeup_function (tr,is_graph (),1 );else -unregister_wakeup_function (is_graph ()); +unregister_wakeup_function (tr,is_graph ()); }static int wakeup_flag_changed (struct trace_array *tr,u32 mask,int set)
@@ -184,16 +178,16 @@ static int wakeup_flag_changed(struct trace_array *tr, u32 mask, int set)struct tracer *tracer = tr->current_trace;if (mask &TRACE_ITER_FUNCTION ) -wakeup_function_set (set); +wakeup_function_set (tr, set);return trace_keep_overwrite (tracer, mask, set); } -static int start_func_tracer (int graph) +static int start_func_tracer (struct trace_array *tr,int graph) {int ret; - ret =register_wakeup_function (graph,0 ); + ret =register_wakeup_function (tr, graph,0 );if (!ret &&tracing_is_enabled ()) tracer_enabled =1 ;
@@ -203,11 +197,11 @@ static int start_func_tracer(int graph)return ret; } -static void stop_func_tracer (int graph) +static void stop_func_tracer (struct trace_array *tr,int graph) { tracer_enabled =0 ; -unregister_wakeup_function (graph); +unregister_wakeup_function (tr, graph); }#ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@ -221,12 +215,12 @@ wakeup_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)if (!(is_graph () ^ set))return 0 ; -stop_func_tracer (!set); +stop_func_tracer (tr, !set);wakeup_reset (wakeup_trace); tracing_max_latency =0 ; -return start_func_tracer (set); +return start_func_tracer (tr, set); }static int wakeup_graph_entry (struct ftrace_graph_ent *trace)
@@ -587,7 +581,7 @@ static void start_wakeup_tracer(struct trace_array *tr)*/ smp_wmb (); -if (start_func_tracer (is_graph ())) +if (start_func_tracer (tr,is_graph ()))printk (KERN_ERR "failed to start wakeup tracer\n" );return ;
@@ -600,7 +594,7 @@ fail_deprobe:static void stop_wakeup_tracer (struct trace_array *tr) { tracer_enabled =0 ; -stop_func_tracer (is_graph ()); +stop_func_tracer (tr,is_graph ());unregister_trace_sched_switch (probe_wakeup_sched_switch,NULL );unregister_trace_sched_wakeup_new (probe_wakeup,NULL );unregister_trace_sched_wakeup (probe_wakeup,NULL );
@@ -617,6 +611,7 @@ static int __wakeup_tracer_init(struct trace_array *tr) tracing_max_latency =0 ; wakeup_trace = tr; +ftrace_init_array_ops (tr, wakeup_tracer_call);start_wakeup_tracer (tr);return 0 ; }
@@ -653,6 +648,7 @@ static void wakeup_tracer_reset(struct trace_array *tr)set_tracer_flag (tr,TRACE_ITER_LATENCY_FMT , lat_flag);set_tracer_flag (tr,TRACE_ITER_OVERWRITE , overwrite_flag); +ftrace_reset_array_ops (tr); }static void wakeup_tracer_start (struct trace_array *tr)
kernel/trace/trace_selftest.c +19 -14
@@ -161,11 +161,6 @@ static struct ftrace_ops test_probe3 = { .flags = FTRACE_OPS_FL_RECURSION_SAFE, }; -static struct ftrace_ops test_global = { - .func = trace_selftest_test_global_func, - .flags =FTRACE_OPS_FL_GLOBAL |FTRACE_OPS_FL_RECURSION_SAFE , -}; -static void print_counts (void ) { printk("(%d %d %d %d %d) ",
@@ -185,7 +180,7 @@ static void reset_counts(void) trace_selftest_test_dyn_cnt =0 ; } -static int trace_selftest_ops (int cnt) +static int trace_selftest_ops (struct trace_array *tr,int cnt) {int save_ftrace_enabled = ftrace_enabled;struct ftrace_ops *dyn_ops;
@@ -220,7 +215,11 @@ static int trace_selftest_ops(int cnt)register_ftrace_function (&test_probe1);register_ftrace_function (&test_probe2);register_ftrace_function (&test_probe3); -register_ftrace_function (&test_global); +/* First time we are running with main function */ +if (cnt >1 ) { +ftrace_init_array_ops (tr, trace_selftest_test_global_func); +register_ftrace_function (tr->ops); + }DYN_FTRACE_TEST_NAME ();
@@ -232,8 +231,10 @@ static int trace_selftest_ops(int cnt) goto out;if (trace_selftest_test_probe3_cnt !=1 ) goto out; -if (trace_selftest_test_global_cnt ==0 ) - goto out; +if (cnt >1 ) { +if (trace_selftest_test_global_cnt ==0 ) + goto out; + }DYN_FTRACE_TEST_NAME2 ();
@@ -269,8 +270,10 @@ static int trace_selftest_ops(int cnt) goto out_free;if (trace_selftest_test_probe3_cnt !=3 ) goto out_free; -if (trace_selftest_test_global_cnt ==0 ) - goto out; +if (cnt >1 ) { +if (trace_selftest_test_global_cnt ==0 ) + goto out; + }if (trace_selftest_test_dyn_cnt ==0 ) goto out_free;
@@ -295,7 +298,9 @@ static int trace_selftest_ops(int cnt)unregister_ftrace_function (&test_probe1);unregister_ftrace_function (&test_probe2);unregister_ftrace_function (&test_probe3); -unregister_ftrace_function (&test_global); +if (cnt >1 ) +unregister_ftrace_function (tr->ops); +ftrace_reset_array_ops (tr);/* Make sure everything is off */ reset_counts ();
@@ -388,7 +393,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, }/* Test the ops with global tracing running */ - ret =trace_selftest_ops (1 ); + ret =trace_selftest_ops (tr,1 ); trace->reset (tr); out:
@@ -399,7 +404,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,/* Test the ops with global tracing off */ if (!ret) - ret =trace_selftest_ops (2 ); + ret =trace_selftest_ops (tr,2 );return ret; }
Signature · 1 line
1.8.5.3
Steven Rostedt
maintainerPATCH 2/8 tracing: Move tracing_max_latency into trace_array
In reply to Steven RostedtFrom: "Steven Rostedt (Red Hat)" <[email protected]>
In preparation for letting the latency tracers be used by instances, remove the global tracing_max_latency variable and add a max_latency field to the trace_array that the latency tracers will now use.
--- kernel/trace/trace.c | 14 ++++++-------- kernel/trace/trace.h | 3 +-- kernel/trace/trace_irqsoff.c | 14 +++++++------- kernel/trace/trace_sched_wakeup.c | 12 ++++++------ kernel/trace/trace_selftest.c | 26 +++++++++++++------------- 5 files changed, 33 insertions(+), 36 deletions(-)
kernel/trace/trace.c +6 -8
@@ -982,8 +982,6 @@ static arch_spinlock_t ftrace_max_lock =unsigned long __read_mostly tracing_thresh;#ifdef CONFIG_TRACER_MAX_TRACE -unsigned long __read_mostly tracing_max_latency; -/* * Copy the new maximum trace into the separate maximum-trace * structure. (this way the maximum trace is permanently saved,
@@ -1000,7 +998,7 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) max_buf->cpu = cpu; max_buf->time_start = data->preempt_timestamp; - max_data->saved_latency = tracing_max_latency; + max_data->saved_latency = tr->max_latency; max_data->critical_start = data->critical_start; max_data->critical_end = data->critical_end;
@@ -6328,6 +6326,11 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer)trace_create_file ("tracing_on" ,0644 , d_tracer, tr, &rb_simple_fops); +#ifdef CONFIG_TRACER_MAX_TRACE +trace_create_file ("tracing_max_latency" ,0644 , d_tracer, + &tr->max_latency, &tracing_max_lat_fops); +#endif +if (ftrace_create_function_files (tr, d_tracer))WARN (1 ,"Could not allocate function filter files" );
@@ -6353,11 +6356,6 @@ static __init int tracer_init_debugfs(void)init_tracer_debugfs (&global_trace, d_tracer); -#ifdef CONFIG_TRACER_MAX_TRACE -trace_create_file ("tracing_max_latency" ,0644 , d_tracer, - &tracing_max_latency, &tracing_max_lat_fops); -#endif -trace_create_file ("tracing_thresh" ,0644 , d_tracer, &tracing_thresh, &tracing_max_lat_fops);
kernel/trace/trace.h +1 -2
@@ -190,6 +190,7 @@ struct trace_array {*/ struct trace_buffer max_buffer;bool allocated_snapshot; +unsigned long max_latency;#endif int buffer_disabled;#ifdef CONFIG_FTRACE_SYSCALLS
@@ -599,8 +600,6 @@ extern unsigned long nsecs_to_usecs(unsigned long nsecs);extern unsigned long tracing_thresh;#ifdef CONFIG_TRACER_MAX_TRACE -extern unsigned long tracing_max_latency; -void update_max_tr (struct trace_array *tr,struct task_struct *tsk,int cpu);void update_max_tr_single (struct trace_array *tr,struct task_struct *tsk,int cpu);
kernel/trace/trace_irqsoff.c +7 -7
@@ -170,7 +170,7 @@ irqsoff_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)for_each_possible_cpu (cpu)per_cpu (tracing_cpu, cpu) =0 ; - tracing_max_latency =0 ; + tr->max_latency =0 ;tracing_reset_online_cpus (&irqsoff_trace->trace_buffer);return start_irqsoff_tracer (irqsoff_trace, set);
@@ -297,13 +297,13 @@ static void irqsoff_print_header(struct seq_file *s)/* * Should this new latency be reported/recorded? */ -static int report_latency (cycle_t delta) +static int report_latency (struct trace_array *tr,cycle_t delta) {if (tracing_thresh) {if (delta < tracing_thresh)return 0 ; }else { -if (delta <= tracing_max_latency) +if (delta <= tr->max_latency)return 0 ; }return 1 ;
@@ -327,13 +327,13 @@ check_critical_timing(struct trace_array *tr, pc =preempt_count (); -if (!report_latency (delta)) +if (!report_latency (tr, delta)) goto out;raw_spin_lock_irqsave (&max_trace_lock, flags);/* check if we are still the max latency */ -if (!report_latency (delta)) +if (!report_latency (tr, delta)) goto out_unlock;__trace_function (tr,CALLER_ADDR0 , parent_ip, flags, pc);
@@ -346,7 +346,7 @@ check_critical_timing(struct trace_array *tr, data->critical_end = parent_ip;if (likely (!is_tracing_stopped ())) { - tracing_max_latency = delta; + tr->max_latency = delta;update_max_tr_single (tr, current, cpu); }
@@ -605,7 +605,7 @@ static void __irqsoff_tracer_init(struct trace_array *tr)set_tracer_flag (tr,TRACE_ITER_OVERWRITE ,1 );set_tracer_flag (tr,TRACE_ITER_LATENCY_FMT ,1 ); - tracing_max_latency =0 ; + tr->max_latency =0 ; irqsoff_trace = tr;/* make sure that the tracer is visible */ smp_wmb ();
kernel/trace/trace_sched_wakeup.c +6 -6
@@ -218,7 +218,7 @@ wakeup_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)stop_func_tracer (tr, !set);wakeup_reset (wakeup_trace); - tracing_max_latency =0 ; + tr->max_latency =0 ;return start_func_tracer (tr, set); }
@@ -344,13 +344,13 @@ static void wakeup_print_header(struct seq_file *s)/* * Should this new latency be reported/recorded? */ -static int report_latency (cycle_t delta) +static int report_latency (struct trace_array *tr,cycle_t delta) {if (tracing_thresh) {if (delta < tracing_thresh)return 0 ; }else { -if (delta <= tracing_max_latency) +if (delta <= tr->max_latency)return 0 ; }return 1 ;
@@ -418,11 +418,11 @@ probe_wakeup_sched_switch(void *ignore,T1 =ftrace_now (cpu); delta =T1 -T0 ; -if (!report_latency (delta)) +if (!report_latency (wakeup_trace, delta)) goto out_unlock;if (likely (!is_tracing_stopped ())) { - tracing_max_latency = delta; + wakeup_trace->max_latency = delta;update_max_tr (wakeup_trace, wakeup_task, wakeup_cpu); }
@@ -609,7 +609,7 @@ static int __wakeup_tracer_init(struct trace_array *tr)set_tracer_flag (tr,TRACE_ITER_OVERWRITE ,1 );set_tracer_flag (tr,TRACE_ITER_LATENCY_FMT ,1 ); - tracing_max_latency =0 ; + tr->max_latency =0 ; wakeup_trace = tr;ftrace_init_array_ops (tr, wakeup_tracer_call);start_wakeup_tracer (tr);
kernel/trace/trace_selftest.c +13 -13
@@ -807,7 +807,7 @@ out:int trace_selftest_startup_irqsoff (struct tracer *trace,struct trace_array *tr) { -unsigned long save_max = tracing_max_latency; +unsigned long save_max = tr->max_latency;unsigned long count;int ret;
@@ -819,7 +819,7 @@ trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr) }/* reset the max latency */ - tracing_max_latency =0 ; + tr->max_latency =0 ;/* disable interrupts for a bit */ local_irq_disable ();udelay (100 );
@@ -846,7 +846,7 @@ trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr) ret =-1 ; } - tracing_max_latency = save_max; + tr->max_latency = save_max;return ret; }
@@ -856,7 +856,7 @@ trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)int trace_selftest_startup_preemptoff (struct tracer *trace,struct trace_array *tr) { -unsigned long save_max = tracing_max_latency; +unsigned long save_max = tr->max_latency;unsigned long count;int ret;
@@ -881,7 +881,7 @@ trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr) }/* reset the max latency */ - tracing_max_latency =0 ; + tr->max_latency =0 ;/* disable preemption for a bit */ preempt_disable ();udelay (100 );
@@ -908,7 +908,7 @@ trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr) ret =-1 ; } - tracing_max_latency = save_max; + tr->max_latency = save_max;return ret; }
@@ -918,7 +918,7 @@ trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr)int trace_selftest_startup_preemptirqsoff (struct tracer *trace,struct trace_array *tr) { -unsigned long save_max = tracing_max_latency; +unsigned long save_max = tr->max_latency;unsigned long count;int ret;
@@ -943,7 +943,7 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array * }/* reset the max latency */ - tracing_max_latency =0 ; + tr->max_latency =0 ;/* disable preemption and interrupts for a bit */ preempt_disable ();
@@ -978,7 +978,7 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array * }/* do the test by disabling interrupts first this time */ - tracing_max_latency =0 ; + tr->max_latency =0 ;tracing_start (); trace->start (tr);
@@ -1009,7 +1009,7 @@ out:tracing_start (); out_no_start: trace->reset (tr); - tracing_max_latency = save_max; + tr->max_latency = save_max;return ret; }
@@ -1062,7 +1062,7 @@ static int trace_wakeup_test_thread(void *data)int trace_selftest_startup_wakeup (struct tracer *trace,struct trace_array *tr) { -unsigned long save_max = tracing_max_latency; +unsigned long save_max = tr->max_latency;struct task_struct *p;struct completion is_ready;unsigned long count;
@@ -1088,7 +1088,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr) }/* reset the max latency */ - tracing_max_latency =0 ; + tr->max_latency =0 ;while (p->on_rq) {/*
@@ -1118,7 +1118,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr) trace->reset (tr);tracing_start (); - tracing_max_latency = save_max; + tr->max_latency = save_max;/* kill the thread */ kthread_stop (p);
Signature · 1 line
1.8.5.3
Steven Rostedt
maintainerPATCH 3/8 tracing: Move ftrace_max_lock into trace_array
In reply to Steven RostedtFrom: "Steven Rostedt (Red Hat)" <[email protected]>
In preparation for having tracers enabled in instances, the max_lock should be unique as updating the max for one tracer is a separate operation than updating it for another tracer using a different max.
--- kernel/trace/trace.c | 40 ++++++++++++++-------------------------- kernel/trace/trace.h | 14 ++++++++++++++ kernel/trace/trace_selftest.c | 4 ++-- 3 files changed, 30 insertions(+), 28 deletions(-)
kernel/trace/trace.c +14 -26
@@ -963,22 +963,6 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)return cnt; } -/* -* ftrace_max_lock is used to protect the swapping of buffers -* when taking a max snapshot. The buffers themselves are -* protected by per_cpu spinlocks. But the action of the swap -* needs its own lock. -* -* This is defined as a arch_spinlock_t in order to help -* with performance when lockdep debugging is enabled. -* -* It is also used in other places outside the update_max_tr -* so it needs to be defined outside of the -* CONFIG_TRACER_MAX_TRACE. -*/ -static arch_spinlock_t ftrace_max_lock = - (arch_spinlock_t )__ARCH_SPIN_LOCK_UNLOCKED; -unsigned long __read_mostly tracing_thresh;#ifdef CONFIG_TRACER_MAX_TRACE
@@ -1046,14 +1030,14 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)return ; } -arch_spin_lock (&ftrace_max_lock); +arch_spin_lock (&tr->max_lock); buf = tr->trace_buffer.buffer; tr->trace_buffer.buffer = tr->max_buffer.buffer; tr->max_buffer.buffer = buf;__update_max_tr (tr, tsk, cpu); -arch_spin_unlock (&ftrace_max_lock); +arch_spin_unlock (&tr->max_lock); }/**
@@ -1079,7 +1063,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)return ; } -arch_spin_lock (&ftrace_max_lock); +arch_spin_lock (&tr->max_lock); ret =ring_buffer_swap_cpu (tr->max_buffer.buffer, tr->trace_buffer.buffer, cpu);
@@ -1097,7 +1081,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)WARN_ON_ONCE (ret && ret != -EAGAIN && ret != -EBUSY );__update_max_tr (tr, tsk, cpu); - arch_spin_unlock(&ftrace_max_lock); + arch_spin_unlock(&tr->max_lock); }#endif /* CONFIG_TRACER_MAX_TRACE */
@@ -1351,7 +1335,7 @@ void tracing_start(void) }/* Prevent the buffers from switching */ -arch_spin_lock (&ftrace_max_lock); +arch_spin_lock (&global_trace.max_lock); buffer = global_trace.trace_buffer.buffer;if (buffer)
@@ -1363,7 +1347,7 @@ void tracing_start(void)ring_buffer_record_enable (buffer);#endif -arch_spin_unlock (&ftrace_max_lock); +arch_spin_unlock (&global_trace.max_lock);ftrace_start (); out:
@@ -1418,7 +1402,7 @@ void tracing_stop(void) goto out;/* Prevent the buffers from switching */ -arch_spin_lock (&ftrace_max_lock); +arch_spin_lock (&global_trace.max_lock); buffer = global_trace.trace_buffer.buffer;if (buffer)
@@ -1430,7 +1414,7 @@ void tracing_stop(void)ring_buffer_record_disable (buffer);#endif -arch_spin_unlock (&ftrace_max_lock); +arch_spin_unlock (&global_trace.max_lock); out:raw_spin_unlock_irqrestore (&global_trace.start_lock, flags);
@@ -3331,7 +3315,7 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf,mutex_lock (&tracing_cpumask_update_lock);local_irq_disable (); -arch_spin_lock (&ftrace_max_lock); +arch_spin_lock (&tr->max_lock);for_each_tracing_cpu (cpu) {/* * Increase/decrease the disabled counter if we are
@@ -3348,7 +3332,7 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf,ring_buffer_record_enable_cpu (tr->trace_buffer.buffer, cpu); } } -arch_spin_unlock (&ftrace_max_lock); +arch_spin_unlock (&tr->max_lock);local_irq_enable ();cpumask_copy (tr->tracing_cpumask, tracing_cpumask_new);
@@ -6129,6 +6113,8 @@ static int new_instance_create(const char *name)raw_spin_lock_init (&tr->start_lock); + tr->max_lock = (arch_spinlock_t )__ARCH_SPIN_LOCK_UNLOCKED; + tr->current_trace = &nop_trace;INIT_LIST_HEAD (&tr->systems);
@@ -6627,6 +6613,8 @@ __init static int tracer_alloc_buffers(void)*/ global_trace.current_trace = &nop_trace; + global_trace.max_lock = (arch_spinlock_t )__ARCH_SPIN_LOCK_UNLOCKED; +ftrace_init_global_array_ops (&global_trace);register_tracer (&nop_trace);
kernel/trace/trace.h +14 -0
@@ -192,6 +192,20 @@ struct trace_array {bool allocated_snapshot;unsigned long max_latency;#endif +/* +* max_lock is used to protect the swapping of buffers +* when taking a max snapshot. The buffers themselves are +* protected by per_cpu spinlocks. But the action of the swap +* needs its own lock. +* +* This is defined as a arch_spinlock_t in order to help +* with performance when lockdep debugging is enabled. +* +* It is also used in other places outside the update_max_tr +* so it needs to be defined outside of the +* CONFIG_TRACER_MAX_TRACE. +*/ +arch_spinlock_t max_lock;int buffer_disabled;#ifdef CONFIG_FTRACE_SYSCALLS int sys_refcount_enter;
kernel/trace/trace_selftest.c +2 -2
@@ -65,7 +65,7 @@ static int trace_test_buffer(struct trace_buffer *buf, unsigned long *count)/* Don't allow flipping of max traces now */ local_irq_save (flags); -arch_spin_lock (&ftrace_max_lock); +arch_spin_lock (&buf->tr->max_lock); cnt =ring_buffer_entries (buf->buffer);
@@ -83,7 +83,7 @@ static int trace_test_buffer(struct trace_buffer *buf, unsigned long *count)break ; }tracing_on (); -arch_spin_unlock (&ftrace_max_lock); +arch_spin_unlock (&buf->tr->max_lock);local_irq_restore (flags);if (count)
Signature · 1 line
1.8.5.3
Steven Rostedt
maintainerPATCH 4/8 tracing: Allow wakeup tracers to be used by instances
In reply to Steven RostedtFrom: "Steven Rostedt (Red Hat)" <[email protected]>
The wakeup and wakeup_rt tracers can now be used by instances. But they may only be used by one instance at a time (including the top level directory). This allows multiple tracers to run while the wakeup tracer is running simultaneously.
--- kernel/trace/trace_sched_wakeup.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
kernel/trace/trace_sched_wakeup.c +16 -0
@@ -601,6 +601,8 @@ static void stop_wakeup_tracer(struct trace_array *tr)unregister_trace_sched_migrate_task (probe_wakeup_migrate_task,NULL ); } +static bool wakeup_busy; +static int __wakeup_tracer_init (struct trace_array *tr) { save_flags = trace_flags;
@@ -613,11 +615,16 @@ static int __wakeup_tracer_init(struct trace_array *tr) wakeup_trace = tr;ftrace_init_array_ops (tr, wakeup_tracer_call);start_wakeup_tracer (tr); + + wakeup_busy = true;return 0 ; }static int wakeup_tracer_init (struct trace_array *tr) { +if (wakeup_busy) +return -EBUSY ; + wakeup_dl =0 ; wakeup_rt =0 ;return __wakeup_tracer_init (tr);
@@ -625,6 +632,9 @@ static int wakeup_tracer_init(struct trace_array *tr)static int wakeup_rt_tracer_init (struct trace_array *tr) { +if (wakeup_busy) +return -EBUSY ; + wakeup_dl =0 ; wakeup_rt =1 ;return __wakeup_tracer_init (tr);
@@ -632,6 +642,9 @@ static int wakeup_rt_tracer_init(struct trace_array *tr)static int wakeup_dl_tracer_init (struct trace_array *tr) { +if (wakeup_busy) +return -EBUSY ; + wakeup_dl =1 ; wakeup_rt =0 ;return __wakeup_tracer_init (tr);
@@ -649,6 +662,7 @@ static void wakeup_tracer_reset(struct trace_array *tr)set_tracer_flag (tr,TRACE_ITER_LATENCY_FMT , lat_flag);set_tracer_flag (tr,TRACE_ITER_OVERWRITE , overwrite_flag);ftrace_reset_array_ops (tr); + wakeup_busy = false; }static void wakeup_tracer_start (struct trace_array *tr)
@@ -680,6 +694,7 @@ static struct tracer wakeup_tracer __read_mostly =#endif .open = wakeup_trace_open, .close = wakeup_trace_close, + .allow_instances = true, .use_max_tr = true, };
@@ -702,6 +717,7 @@ static struct tracer wakeup_rt_tracer __read_mostly =#endif .open = wakeup_trace_open, .close = wakeup_trace_close, + .allow_instances = true, .use_max_tr = true, };
Signature · 1 line
1.8.5.3
Steven Rostedt
maintainerPATCH 5/8 tracing: Allow irq/preempt tracers to be used by instances
In reply to Steven RostedtFrom: "Steven Rostedt (Red Hat)" <[email protected]>
The irqsoff, preemptoff and preemptirqsoff tracers can now be used by instances. But they may only be used by one instance at a time (including the top level directory). This allows multiple tracers to run while the irqsoff (and friends) tracer is running simultaneously.
--- kernel/trace/trace_irqsoff.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-)
kernel/trace/trace_irqsoff.c +17 -7
@@ -597,8 +597,13 @@ static void stop_irqsoff_tracer(struct trace_array *tr, int graph)unregister_irqsoff_function (tr, graph); } -static void __irqsoff_tracer_init (struct trace_array *tr) +static bool irqsoff_busy; + +static int __irqsoff_tracer_init (struct trace_array *tr) { +if (irqsoff_busy) +return -EBUSY ; + save_flags = trace_flags;/* non overwrite screws up the latency tracers */
@@ -617,6 +622,9 @@ static void __irqsoff_tracer_init(struct trace_array *tr)if (start_irqsoff_tracer (tr, (tr->flags &TRACE_ARRAY_FL_GLOBAL &&is_graph ())))printk (KERN_ERR "failed to start irqsoff tracer\n" ); + + irqsoff_busy = true; +return 0 ; }static void irqsoff_tracer_reset (struct trace_array *tr)
@@ -629,6 +637,8 @@ static void irqsoff_tracer_reset(struct trace_array *tr)set_tracer_flag (tr,TRACE_ITER_LATENCY_FMT , lat_flag);set_tracer_flag (tr,TRACE_ITER_OVERWRITE , overwrite_flag);ftrace_reset_array_ops (tr); + + irqsoff_busy = false; }static void irqsoff_tracer_start (struct trace_array *tr)
@@ -646,8 +656,7 @@ static int irqsoff_tracer_init(struct trace_array *tr) { trace_type =TRACER_IRQS_OFF ; -__irqsoff_tracer_init (tr); -return 0 ; +return __irqsoff_tracer_init (tr); }static struct tracer irqsoff_tracer__read_mostly = {
@@ -667,6 +676,7 @@ static struct tracer irqsoff_tracer __read_mostly =#endif .open = irqsoff_trace_open, .close = irqsoff_trace_close, + .allow_instances = true, .use_max_tr = true, };# define register_irqsoff (trace) register_tracer(&trace)
@@ -679,8 +689,7 @@ static int preemptoff_tracer_init(struct trace_array *tr) { trace_type =TRACER_PREEMPT_OFF ; -__irqsoff_tracer_init (tr); -return 0 ; +return __irqsoff_tracer_init (tr); } static struct tracer preemptoff_tracer __read_mostly =
@@ -701,6 +710,7 @@ static struct tracer preemptoff_tracer __read_mostly =#endif .open = irqsoff_trace_open, .close = irqsoff_trace_close, + .allow_instances = true, .use_max_tr = true, };# define register_preemptoff (trace) register_tracer(&trace)
@@ -715,8 +725,7 @@ static int preemptirqsoff_tracer_init(struct trace_array *tr) { trace_type =TRACER_IRQS_OFF |TRACER_PREEMPT_OFF ; -__irqsoff_tracer_init (tr); -return 0 ; +return __irqsoff_tracer_init (tr); } static struct tracer preemptirqsoff_tracer __read_mostly =
@@ -737,6 +746,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly =#endif .open = irqsoff_trace_open, .close = irqsoff_trace_close, + .allow_instances = true, .use_max_tr = true, };
Signature · 1 line
1.8.5.3
Steven Rostedt
maintainerPATCH 6/8 ftrace/x86: Fix order of warning messages when ftrace modifies code
In reply to Steven RostedtFrom: Petr Mladek <[email protected]>
The colon at the end of the printk message suggests that it should get printed before the details printed by ftrace_bug().
When touching the line, let's use the preferred pr_warn() macro as suggested by checkpatch.pl.
--- arch/x86/kernel/ftrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/ftrace.c +1 -1
@@ -621,8 +621,8 @@ void ftrace_replace_code(int enable)return ; remove_breakpoints: +pr_warn ("Failed on %s (%d):\n" , report, count);ftrace_bug (ret, rec ? rec->ip :0 ); -printk (KERN_WARNING "Failed on %s (%d):\n" , report, count);for_ftrace_rec_iter (iter) { rec =ftrace_rec_iter_record (iter);/*
Signature · 1 line
1.8.5.3
Steven Rostedt
maintainerPATCH 7/8 ftrace: Statically initialize pm notifier block
In reply to Steven RostedtFrom: Mathias Krause <[email protected]>
Instead of initializing the pm notifier block in register_ftrace_graph(), initialize it statically. This safes us some code.
Found in the PaX patch, written by the PaX Team.
--- kernel/trace/ftrace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
kernel/trace/ftrace.c +4 -2
@@ -4860,7 +4860,6 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,#ifdef CONFIG_FUNCTION_GRAPH_TRACER static int ftrace_graph_active; -static struct notifier_block ftrace_suspend_notifier;int ftrace_graph_entry_stub (struct ftrace_graph_ent *trace) {
@@ -5036,6 +5035,10 @@ static void update_function_graph_func(void) ftrace_graph_entry = ftrace_graph_entry_test; } +static struct notifier_block ftrace_suspend_notifier = { + .notifier_call = ftrace_suspend_notifier_call, +}; +int register_ftrace_graph (trace_func_graph_ret_t retfunc,trace_func_graph_ent_t entryfunc) {
@@ -5049,7 +5052,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, goto out; } - ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;register_pm_notifier (&ftrace_suspend_notifier); ftrace_graph_active++;
Signature · 1 line
1.8.5.3
Steven Rostedt
maintainerPATCH 8/8 tracing: Add static to local functions
In reply to Steven RostedtFrom: Fabian Frederick <[email protected]>
This patch adds static to the following functions:
-cycle_t buffer_ftrace_now
-void free_snapshot
-int trace_selftest_startup_dynamic_tracing
--- kernel/trace/trace.c | 4 ++-- kernel/trace/trace_selftest.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-)
kernel/trace/trace.c +2 -2
@@ -275,7 +275,7 @@ int call_filter_check_discard(struct ftrace_event_call *call, void *rec, }EXPORT_SYMBOL_GPL (call_filter_check_discard); -cycle_t buffer_ftrace_now (struct trace_buffer *buf,int cpu) +static cycle_t buffer_ftrace_now (struct trace_buffer *buf,int cpu) {u64 ts;
@@ -599,7 +599,7 @@ static int alloc_snapshot(struct trace_array *tr)return 0 ; } -void free_snapshot (struct trace_array *tr) +static void free_snapshot (struct trace_array *tr) {/* * We don't free the ring buffer. instead, resize it because
kernel/trace/trace_selftest.c +3 -3
@@ -320,9 +320,9 @@ static int trace_selftest_ops(struct trace_array *tr, int cnt) }/* Test dynamic code modification and ftrace filters */ -int trace_selftest_startup_dynamic_tracing (struct tracer *trace, -struct trace_array *tr, -int (*func)(void )) +static int trace_selftest_startup_dynamic_tracing (struct tracer *trace, +struct trace_array *tr, +int (*func)(void )) {int save_ftrace_enabled = ftrace_enabled;unsigned long count;
Signature · 1 line
1.8.5.3