[3.8] tracing: updates
Subsystems (22)
Steven Rostedt
maintainerIngo,
I've been focusing on -rt related things lately and let my tracing queue pile up on me. I've ran these through my own vigorous tests, and think they are ready for 3.8.
Please pull the latest tip/perf/core tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
tip/perf/core
Head SHA1: 9b194e6cb864506da693d26149370cb7272af99f
Daniel Walter (1):
tracing: Replace strict_strto* with kstrto*
David Sharp (4):
tracing: Trivial cleanup
tracing,x86: Add a TSC trace_clock
tracing: Reset ring buffer when changing trace_clocks
tracing: Format non-nanosec times from tsc clock without a decimal point.
Hiraku Toyooka (1):
tracing: Change tracer's integer flags to bool
Michal Hocko (1):
linux/kernel.h: Remove duplicate trace_printk declaration
Slava Pestov (1):
ring-buffer: Add a 'dropped events' counter
Steven Rostedt (11):
tracing: Allow tracers to start at core initcall
tracing: Expand ring buffer when trace_printk() is used
tracing: Enable comm recording if trace_printk() is used
tracing: Have tracing_sched_wakeup_trace() use standard unlock_commit
tracing: Cache comms only after an event occurred
tracing: Separate open function from set_event and available_events
tracing: Remove unused function unregister_tracer()
tracing: Make tracing_enabled be equal to tracing_on
tracing: Remove deprecated tracing_enabled file
tracing: Use irq_work for wake ups and remove *_nowake_*() functions
tracing: Add trace_options kernel command line parameter
Vaibhav Nagarnaik (1):
tracing: Cleanup unnecessary function declarations
Yoshihiro YUNOMAE (2):
ring-buffer: Change unsigned long type of ring_buffer_oldest_event_ts() to u64
tracing: Show raw time stamp on stats per cpu using counter or tsc mode for trace_clock
----
Documentation/kernel-parameters.txt | 16 ++ arch/alpha/include/asm/Kbuild | 1 + arch/arm/include/asm/Kbuild | 1 + arch/arm64/include/asm/Kbuild | 1 + arch/avr32/include/asm/Kbuild | 1 + arch/blackfin/include/asm/Kbuild | 1 + arch/c6x/include/asm/Kbuild | 1 + arch/cris/include/asm/Kbuild | 1 + arch/frv/include/asm/Kbuild | 1 + arch/h8300/include/asm/Kbuild | 1 + arch/hexagon/include/asm/Kbuild | 1 + arch/ia64/include/asm/Kbuild | 1 + arch/m32r/include/asm/Kbuild | 1 + arch/m68k/include/asm/Kbuild | 1 + arch/microblaze/include/asm/Kbuild | 1 + arch/mips/include/asm/Kbuild | 1 + arch/mn10300/include/asm/Kbuild | 1 + arch/openrisc/include/asm/Kbuild | 1 + arch/parisc/include/asm/Kbuild | 2 +- arch/powerpc/include/asm/Kbuild | 1 + arch/s390/include/asm/Kbuild | 1 + arch/score/include/asm/Kbuild | 1 + arch/sh/include/asm/Kbuild | 1 + arch/sparc/include/asm/Kbuild | 1 + arch/tile/include/asm/Kbuild | 1 + arch/um/include/asm/Kbuild | 1 + arch/unicore32/include/asm/Kbuild | 1 + arch/x86/include/asm/trace_clock.h | 16 ++ arch/x86/kernel/Makefile | 1 + arch/x86/kernel/trace_clock.c | 21 ++ arch/xtensa/include/asm/Kbuild | 1 + include/asm-generic/trace_clock.h | 16 ++ include/linux/ftrace_event.h | 20 +- include/linux/kernel.h | 7 +- include/linux/ring_buffer.h | 3 +- include/linux/trace_clock.h | 2 + include/trace/ftrace.h | 3 +- include/trace/syscall.h | 23 -- kernel/trace/Kconfig | 1 + kernel/trace/ftrace.c | 6 +- kernel/trace/ring_buffer.c | 51 ++++- kernel/trace/trace.c | 411 ++++++++++++++++++---------------- kernel/trace/trace.h | 18 +- kernel/trace/trace_branch.c | 4 +- kernel/trace/trace_events.c | 51 +++-- kernel/trace/trace_events_filter.c | 4 +- kernel/trace/trace_functions.c | 5 +- kernel/trace/trace_functions_graph.c | 6 +- kernel/trace/trace_irqsoff.c | 14 +- kernel/trace/trace_kprobe.c | 10 +- kernel/trace/trace_output.c | 80 ++++--- kernel/trace/trace_probe.c | 14 +- kernel/trace/trace_sched_switch.c | 4 +- kernel/trace/trace_sched_wakeup.c | 10 +- kernel/trace/trace_selftest.c | 13 +- kernel/trace/trace_syscalls.c | 61 +++-- kernel/trace/trace_uprobe.c | 2 +- 57 files changed, 539 insertions(+), 382 deletions(-)
Steven Rostedt
maintainerPATCH 1/22 tracing: Replace strict_strto* with kstrto*
From: Daniel Walter <[email protected]>
* remove old string conversions with kstrto*
--- kernel/trace/ftrace.c | 2 +- kernel/trace/trace.c | 2 +- kernel/trace/trace_events_filter.c | 4 ++-- kernel/trace/trace_functions.c | 2 +- kernel/trace/trace_kprobe.c | 2 +- kernel/trace/trace_probe.c | 14 +++++++------- kernel/trace/trace_uprobe.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-)
kernel/trace/ftrace.c +1 -1
@@ -4381,7 +4381,7 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf,if (strlen (tmp) ==0 )return 1 ; - ret =strict_strtol (tmp,10 , &val); + ret =kstrtol (tmp,10 , &val);if (ret <0 )return ret;
kernel/trace/trace.c +1 -1
@@ -431,7 +431,7 @@ static int __init set_tracing_thresh(char *str)if (!str)return 0 ; - ret =strict_strtoul (str,0 , &threshold); + ret =kstrtoul (str,0 , &threshold);if (ret <0 )return 0 ; tracing_thresh = threshold *1000 ;
kernel/trace/trace_events_filter.c +2 -2
@@ -1000,9 +1000,9 @@ static int init_pred(struct filter_parse_state *ps, } }else {if (field->is_signed) - ret =strict_strtoll (pred->regex.pattern,0 , &val); + ret =kstrtoll (pred->regex.pattern,0 , &val);else - ret =strict_strtoull (pred->regex.pattern,0 , &val); + ret =kstrtoull (pred->regex.pattern,0 , &val);if (ret) {parse_error (ps,FILT_ERR_ILLEGAL_INTVAL ,0 );return -EINVAL ;
kernel/trace/trace_functions.c +1 -1
@@ -366,7 +366,7 @@ ftrace_trace_onoff_callback(struct ftrace_hash *hash,* We use the callback data field (which is a pointer) * as our counter. */ - ret =strict_strtoul (number,0 , (unsigned long *)&count); + ret =kstrtoul (number,0 , (unsigned long *)&count);if (ret)return ret;
kernel/trace/trace_kprobe.c +1 -1
@@ -444,7 +444,7 @@ static int create_trace_probe(int argc, char **argv)return -EINVAL ; }/* an address specified */ - ret =strict_strtoul (&argv[1 ][0 ],0 , (unsigned long *)&addr); + ret =kstrtoul (&argv[1 ][0 ],0 , (unsigned long *)&addr);if (ret) {pr_info ("Failed to parse address.\n" );return ret;
kernel/trace/trace_probe.c +7 -7
@@ -441,7 +441,7 @@ static const struct fetch_type *find_fetch_type(const char *type) goto fail; type++; -if (strict_strtoul (type,0 , &bs)) +if (kstrtoul (type,0 , &bs)) goto fail;switch (bs) {
@@ -501,8 +501,8 @@ int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) tmp =strchr (symbol,'+' );if (tmp) { -/* skip sign because strict_strtol doesn't accept '+' */ - ret =strict_strtoul (tmp +1 ,0 , offset); +/* skip sign because kstrtoul doesn't accept '+' */ + ret =kstrtoul (tmp +1 ,0 , offset);if (ret)return ret;
@@ -533,7 +533,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,else ret = -EINVAL ; }else if (isdigit (arg[5 ])) { - ret =strict_strtoul (arg +5 ,10 , ¶m); + ret =kstrtoul (arg +5 ,10 , ¶m);if (ret || param >PARAM_MAX_STACK ) ret = -EINVAL ;else {
@@ -579,7 +579,7 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,case '@' :/* memory or symbol */ if (isdigit (arg[1 ])) { - ret =strict_strtoul (arg +1 ,0 , ¶m); + ret =kstrtoul (arg +1 ,0 , ¶m);if (ret)break ;
@@ -597,14 +597,14 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,break ;case '+' :/* deref memory */ - arg++;/* Skip '+', because strict_strtol() rejects it. */ + arg++;/* Skip '+', because kstrtol() rejects it. */ case '-' : tmp =strchr (arg,'(' );if (!tmp)break ; *tmp ='\0' ; - ret =strict_strtol (arg,0 , &offset); + ret =kstrtol (arg,0 , &offset);if (ret)break ;
kernel/trace/trace_uprobe.c +1 -1
@@ -252,7 +252,7 @@ static int create_trace_uprobe(int argc, char **argv)if (ret) goto fail_address_parse; - ret =strict_strtoul (arg,0 , &offset); + ret =kstrtoul (arg,0 , &offset);if (ret) goto fail_address_parse;
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 2/22 tracing: Allow tracers to start at core initcall
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
There's times during debugging that it is helpful to see traces of early boot functions. But the tracers are initialized at device_initcall() which is quite late during the boot process. Setting the kernel command line parameter ftrace=function will not show anything until the function tracer is initialized. This prevents being able to trace functions before device_initcall().
There's no reason that the tracers need to be initialized so late in the boot process. Move them up to core_initcall() as they still need to come after early_initcall() which initializes the tracing buffers.
--- kernel/trace/ftrace.c | 4 ++-- kernel/trace/trace_branch.c | 2 +- kernel/trace/trace_functions.c | 3 +-- kernel/trace/trace_functions_graph.c | 2 +- kernel/trace/trace_irqsoff.c | 2 +- kernel/trace/trace_sched_wakeup.c | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-)
kernel/trace/ftrace.c +2 -2
@@ -2868,7 +2868,7 @@ static int __init ftrace_mod_cmd_init(void) {return register_ftrace_command (&ftrace_mod_cmd); } -device_initcall (ftrace_mod_cmd_init); +core_initcall (ftrace_mod_cmd_init);static void function_trace_probe_call (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct pt_regs *pt_regs)
@@ -4055,7 +4055,7 @@ static int __init ftrace_nodyn_init(void) ftrace_enabled =1 ;return 0 ; } -device_initcall (ftrace_nodyn_init); +core_initcall (ftrace_nodyn_init);static inline int ftrace_init_dyn_debugfs (struct dentry *d_tracer) {return 0 ; }static inline void ftrace_startup_enable (int command) { }
kernel/trace/trace_branch.c +1 -1
@@ -199,7 +199,7 @@ __init static int init_branch_tracer(void) }return register_tracer (&branch_trace); } -device_initcall (init_branch_tracer); +core_initcall (init_branch_tracer);#else static inline
kernel/trace/trace_functions.c +1 -2
@@ -411,5 +411,4 @@ static __init int init_function_trace(void)init_func_cmd_traceon ();return register_tracer (&function_trace); } -device_initcall (init_function_trace); - +core_initcall (init_function_trace);
kernel/trace/trace_functions_graph.c +1 -1
@@ -1474,4 +1474,4 @@ static __init int init_graph_trace(void)return register_tracer (&graph_trace); } -device_initcall (init_graph_trace); +core_initcall (init_graph_trace);
kernel/trace/trace_irqsoff.c +1 -1
@@ -698,4 +698,4 @@ __init static int init_irqsoff_tracer(void)return 0 ; } -device_initcall (init_irqsoff_tracer); +core_initcall (init_irqsoff_tracer);
kernel/trace/trace_sched_wakeup.c +1 -1
@@ -637,4 +637,4 @@ __init static int init_wakeup_tracer(void)return 0 ; } -device_initcall (init_wakeup_tracer); +core_initcall (init_wakeup_tracer);
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 3/22 tracing: Change tracers integer flags to bool
In reply to Steven RostedtFrom: Hiraku Toyooka <[email protected]>
print_max and use_max_tr in struct tracer are "int" variables and used like flags. This is wasteful, so change the type to "bool".
--- kernel/trace/trace.h | 4 ++-- kernel/trace/trace_irqsoff.c | 12 ++++++------ kernel/trace/trace_sched_wakeup.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-)
kernel/trace/trace.h +2 -2
@@ -285,8 +285,8 @@ struct tracer {int (*set_flag)(u32 old_flags,u32 bit,int set);struct tracer *next;struct tracer_flags *flags; -int print_max; -int use_max_tr; +bool print_max; +bool use_max_tr; };
kernel/trace/trace_irqsoff.c +6 -6
@@ -604,7 +604,7 @@ static struct tracer irqsoff_tracer __read_mostly = .reset = irqsoff_tracer_reset, .start = irqsoff_tracer_start, .stop = irqsoff_tracer_stop, - .print_max = 1, + .print_max = true, .print_header = irqsoff_print_header, .print_line = irqsoff_print_line, .flags = &tracer_flags,
@@ -614,7 +614,7 @@ static struct tracer irqsoff_tracer __read_mostly =#endif .open = irqsoff_trace_open, .close = irqsoff_trace_close, - .use_max_tr = 1, + .use_max_tr = true, };# define register_irqsoff (trace) register_tracer(&trace)#else
@@ -637,7 +637,7 @@ static struct tracer preemptoff_tracer __read_mostly = .reset = irqsoff_tracer_reset, .start = irqsoff_tracer_start, .stop = irqsoff_tracer_stop, - .print_max = 1, + .print_max = true, .print_header = irqsoff_print_header, .print_line = irqsoff_print_line, .flags = &tracer_flags,
@@ -647,7 +647,7 @@ static struct tracer preemptoff_tracer __read_mostly =#endif .open = irqsoff_trace_open, .close = irqsoff_trace_close, - .use_max_tr = 1, + .use_max_tr = true, };# define register_preemptoff (trace) register_tracer(&trace)#else
@@ -672,7 +672,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly = .reset = irqsoff_tracer_reset, .start = irqsoff_tracer_start, .stop = irqsoff_tracer_stop, - .print_max = 1, + .print_max = true, .print_header = irqsoff_print_header, .print_line = irqsoff_print_line, .flags = &tracer_flags,
@@ -682,7 +682,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly =#endif .open = irqsoff_trace_open, .close = irqsoff_trace_close, - .use_max_tr = 1, + .use_max_tr = true, };# define register_preemptirqsoff (trace) register_tracer(&trace)
kernel/trace/trace_sched_wakeup.c +4 -4
@@ -589,7 +589,7 @@ static struct tracer wakeup_tracer __read_mostly = .reset = wakeup_tracer_reset, .start = wakeup_tracer_start, .stop = wakeup_tracer_stop, - .print_max = 1, + .print_max = true, .print_header = wakeup_print_header, .print_line = wakeup_print_line, .flags = &tracer_flags,
@@ -599,7 +599,7 @@ static struct tracer wakeup_tracer __read_mostly =#endif .open = wakeup_trace_open, .close = wakeup_trace_close, - .use_max_tr = 1, + .use_max_tr = true, }; static struct tracer wakeup_rt_tracer __read_mostly =
@@ -610,7 +610,7 @@ static struct tracer wakeup_rt_tracer __read_mostly = .start = wakeup_tracer_start, .stop = wakeup_tracer_stop, .wait_pipe = poll_wait_pipe, - .print_max = 1, + .print_max = true, .print_header = wakeup_print_header, .print_line = wakeup_print_line, .flags = &tracer_flags,
@@ -620,7 +620,7 @@ static struct tracer wakeup_rt_tracer __read_mostly =#endif .open = wakeup_trace_open, .close = wakeup_trace_close, - .use_max_tr = 1, + .use_max_tr = true, };__init static int init_wakeup_tracer (void )
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 4/22 ring-buffer: Add a dropped events counter
In reply to Steven RostedtFrom: Slava Pestov <[email protected]>
The existing 'overrun' counter is incremented when the ring buffer wraps around, with overflow on (the default). We wanted a way to count requests lost from the buffer filling up with overflow off, too. I decided to add a new counter instead of retro-fitting the existing one because it seems like a different statistic to count conceptually, and also because of how the code was structured.
--- include/linux/ring_buffer.h | 1 + kernel/trace/ring_buffer.c | 41 +++++++++++++++++++++++++++++++++++------ kernel/trace/trace.c | 3 +++ 3 files changed, 39 insertions(+), 6 deletions(-)
include/linux/ring_buffer.h +1 -0
@@ -166,6 +166,7 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer);unsigned long ring_buffer_entries_cpu (struct ring_buffer *buffer,int cpu);unsigned long ring_buffer_overrun_cpu (struct ring_buffer *buffer,int cpu);unsigned long ring_buffer_commit_overrun_cpu (struct ring_buffer *buffer,int cpu); +unsigned long ring_buffer_dropped_events_cpu (struct ring_buffer *buffer,int cpu);u64 ring_buffer_time_stamp (struct ring_buffer *buffer,int cpu); void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
kernel/trace/ring_buffer.c +35 -6
81 lines not on this page · raw message
kernel/trace/trace.c +3 -0
@@ -4385,6 +4385,9 @@ tracing_stats_read(struct file *filp, char __user *ubuf, usec_rem =do_div (t,USEC_PER_SEC );trace_seq_printf (s,"now ts: %5llu.%06lu\n" , t, usec_rem); + cnt =ring_buffer_dropped_events_cpu (tr->buffer, cpu); +trace_seq_printf (s,"dropped events: %ld\n" , cnt); + count =simple_read_from_buffer (ubuf, count, ppos, s->buffer, s->len);kfree (s);
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 5/22 tracing: Expand ring buffer when trace_printk() is used
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Since tracing is not used by 99% of Linux users, even though tracing may be configured in, it does not make sense to allocate 1.4 Megs per CPU for the ring buffers if they are not used. Thus, on boot up the ring buffers are set to a minimal size until something needs the and they are expanded.
This works well for events and tracers (function, etc), but for the asynchronous use of trace_printk() which can write to the ring buffer at any time, does not expand the buffers.
On boot up a check is made to see if any trace_printk() is used to see if the trace_printk() temp buffer pages should be allocated. This same code can be used to expand the buffers as well.
--- kernel/trace/trace.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/trace/trace.c +7 -0
@@ -1571,6 +1571,9 @@ void trace_printk_init_buffers(void)pr_info ("ftrace: Allocated trace_printk buffers\n" ); +/* Expand the buffers to set size */ +tracing_update_buffers (); + buffers_allocated =1 ; }
@@ -3030,6 +3033,10 @@ static int __tracing_resize_ring_buffer(unsigned long size, int cpu)*/ ring_buffer_expanded =1 ; +/* May be called before buffers are initialized */ +if (!global_trace.buffer) +return 0 ; + ret =ring_buffer_resize (global_trace.buffer, size, cpu);if (ret <0 )return ret;
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 6/22 tracing: Enable comm recording if trace_printk() is used
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
If comm recording is not enabled when trace_printk() is used then you just get this type of output:
[ adding trace_printk("hello! %d", irq); in do_IRQ ]
<...>-2843 [001] d.h. 80.812300: do_IRQ: hello! 14
<...>-2734 [002] d.h2 80.824664: do_IRQ: hello! 14
<...>-2713 [003] d.h. 80.829971: do_IRQ: hello! 14
<...>-2814 [000] d.h. 80.833026: do_IRQ: hello! 14By enabling the comm recorder when trace_printk is enabled:
hackbench-6715 [001] d.h. 193.233776: do_IRQ: hello! 21
sshd-2659 [001] d.h. 193.665862: do_IRQ: hello! 21
<idle>-0 [001] d.h1 193.665996: do_IRQ: hello! 21--- kernel/trace/trace.c | 36 ++++++++++++++++++++++++++++++++++-- kernel/trace/trace.h | 1 + kernel/trace/trace_events.c | 3 +++ 3 files changed, 38 insertions(+), 2 deletions(-)
kernel/trace/trace.c +34 -2
@@ -1559,10 +1559,10 @@ static int alloc_percpu_trace_buffer(void)return -ENOMEM ; } +static int buffers_allocated; +void trace_printk_init_buffers (void ) { -static int buffers_allocated; -if (buffers_allocated)return ;
@@ -1575,6 +1575,34 @@ void trace_printk_init_buffers(void)tracing_update_buffers (); buffers_allocated =1 ; + +/* +* trace_printk_init_buffers() can be called by modules. +* If that happens, then we need to start cmdline recording +* directly here. If the global_trace.buffer is already +* allocated here, then this was called by module code. +*/ +if (global_trace.buffer) +tracing_start_cmdline_record (); +} + +void trace_printk_start_comm (void ) +{ +/* Start tracing comms if trace printk is set */ +if (!buffers_allocated) +return ; +tracing_start_cmdline_record (); +} + +static void trace_printk_start_stop_comm (int enabled) +{ +if (!buffers_allocated) +return ; + +if (enabled) +tracing_start_cmdline_record (); +else +tracing_stop_cmdline_record (); }/**
@@ -2797,6 +2825,9 @@ static void set_tracer_flags(unsigned int mask, int enabled)if (mask ==TRACE_ITER_OVERWRITE )ring_buffer_change_overwrite (global_trace.buffer, enabled); + +if (mask ==TRACE_ITER_PRINTK ) +trace_printk_start_stop_comm (enabled); } static ssize_t
@@ -5099,6 +5130,7 @@ __init static int tracer_alloc_buffers(void)/* Only allocate trace_printk buffers if a trace_printk exists */ if (__stop___trace_bprintk_fmt != __start___trace_bprintk_fmt) +/* Must be called before global_trace.buffer is allocated */ trace_printk_init_buffers ();/* To save memory, keep the ring buffer size to its minimum */
kernel/trace/trace.h +1 -0
@@ -841,6 +841,7 @@ extern const char *__start___trace_bprintk_fmt[];extern const char *__stop___trace_bprintk_fmt[];void trace_printk_init_buffers (void ); +void trace_printk_start_comm (void );#undef FTRACE_ENTRY#define FTRACE_ENTRY (call, struct_name, id, tstruct, print, filter) \
kernel/trace/trace_events.c +3 -0
@@ -1489,6 +1489,9 @@ static __init int event_trace_enable(void)if (ret)pr_warn ("Failed to enable trace event: %s\n" , token); } + +trace_printk_start_comm (); +return 0 ; }
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 7/22 tracing: Have tracing_sched_wakeup_trace() use standard unlock_commit
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The functon tracing_sched_wakeup_trace() does an open coded unlock commit and save stack. This is what the trace_nowake_buffer_unlock_commit() is for.
--- kernel/trace/trace_sched_switch.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
kernel/trace/trace_sched_switch.c +1 -3
@@ -102,9 +102,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->next_cpu =task_cpu (wakee);if (!filter_check_discard (call, entry, buffer, event)) -ring_buffer_unlock_commit (buffer, event); -ftrace_trace_stack (tr->buffer, flags,6 , pc); -ftrace_trace_userstack (tr->buffer, flags, pc); +trace_nowake_buffer_unlock_commit (buffer, event, flags, pc); } static void
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 8/22 tracing: Cache comms only after an event occurred
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Whenever an event is registered, the comm of tasks are saved at every task switch instead of saving them at every event. But if an event isn't executed much, the comm cache will be filled up by tasks that did not record the event and you lose out on the comms that did.
Here's an example, if you enable the following events:
echo 1 > /debug/tracing/events/kvm/kvm_cr/enable echo 1 > /debug/tracing/events/net/net_dev_xmit/enable
Note, there's no kvm running on this machine so the first event will never be triggered, but because it is enabled, the storing of comms will continue. If we now disable the network event:
echo 0 > /debug/tracing/events/net/net_dev_xmit/enable
and look at the trace:
cat /debug/tracing/trace
sshd-2672 [001] ..s2 375.731616: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0
sshd-2672 [001] ..s1 375.731617: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0
sshd-2672 [001] ..s2 375.859356: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0
sshd-2672 [001] ..s1 375.859357: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0
sshd-2672 [001] ..s2 375.947351: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0
sshd-2672 [001] ..s1 375.947352: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0
sshd-2672 [001] ..s2 376.035383: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0
sshd-2672 [001] ..s1 376.035383: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0
sshd-2672 [001] ..s2 377.563806: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=226 rc=0
sshd-2672 [001] ..s1 377.563807: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=226 rc=0
sshd-2672 [001] ..s2 377.563834: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6be0 len=114 rc=0
sshd-2672 [001] ..s1 377.563842: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6be0 len=114 rc=0We see that process 2672 which triggered the events has the comm "sshd". But if we run hackbench for a bit and look again:
cat /debug/tracing/trace
<...>-2672 [001] ..s2 375.731616: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0
<...>-2672 [001] ..s1 375.731617: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0
<...>-2672 [001] ..s2 375.859356: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0
<...>-2672 [001] ..s1 375.859357: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0
<...>-2672 [001] ..s2 375.947351: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0
<...>-2672 [001] ..s1 375.947352: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0
<...>-2672 [001] ..s2 376.035383: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0
<...>-2672 [001] ..s1 376.035383: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0
<...>-2672 [001] ..s2 377.563806: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=226 rc=0
<...>-2672 [001] ..s1 377.563807: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=226 rc=0
<...>-2672 [001] ..s2 377.563834: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6be0 len=114 rc=0
<...>-2672 [001] ..s1 377.563842: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6be0 len=114 rc=0The stored "sshd" comm has been flushed out and we get a useless "<...>".
But by only storing comms after a trace event occurred, we can run hackbench all day and still get the same output.
--- kernel/trace/trace.c | 35 ++++++++++++++++++++++++++-------- kernel/trace/trace.h | 3 +++ kernel/trace/trace_branch.c | 2 +- kernel/trace/trace_functions_graph.c | 4 ++-- 4 files changed, 33 insertions(+), 11 deletions(-)
kernel/trace/trace.c +27 -8
@@ -78,6 +78,13 @@ static int dummy_set_flag(u32 old_flags, u32 bit, int set) }/* +* To prevent the comm cache from being overwritten when no +* tracing is active, only save the comm when a trace event +* occurred. +*/ +static DEFINE_PER_CPU(bool, trace_cmdline_save); + +/* * Kill all tracing for good (never come back). * It is initialized to 1 but will turn to zero if the initialization * of the tracer is successful. But that is the only place that sets
@@ -1135,6 +1142,11 @@ void tracing_record_cmdline(struct task_struct *tsk) !tracing_is_on())return ; +if (!__this_cpu_read (trace_cmdline_save)) +return ; + +__this_cpu_write (trace_cmdline_save, false); +trace_save_cmdline (tsk); }
@@ -1178,13 +1190,20 @@ trace_buffer_lock_reserve(struct ring_buffer *buffer,return event; } +void +__buffer_unlock_commit (struct ring_buffer *buffer,struct ring_buffer_event *event) +{ +__this_cpu_write (trace_cmdline_save, true); +ring_buffer_unlock_commit (buffer, event); +} +static inline void __trace_buffer_unlock_commit (struct ring_buffer *buffer,struct ring_buffer_event *event,unsigned long flags,int pc,int wake) { -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event);ftrace_trace_stack (buffer, flags,6 , pc);ftrace_trace_userstack (buffer, flags, pc);
@@ -1232,7 +1251,7 @@ void trace_nowake_buffer_unlock_commit_regs(struct ring_buffer *buffer, unsigned long flags, int pc, struct pt_regs *regs) { -ring_buffer_unlock_commit (buffer ,event ); +__buffer_unlock_commit (buffer ,event );ftrace_trace_stack_regs (buffer, flags,0 , pc, regs);ftrace_trace_userstack (buffer, flags, pc);
@@ -1269,7 +1288,7 @@ trace_function(struct trace_array *tr, entry->parent_ip = parent_ip;if (!filter_check_discard (call, entry, buffer, event)) -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event); }void
@@ -1362,7 +1381,7 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer, entry->size = trace.nr_entries;if (!filter_check_discard (call, entry, buffer, event)) -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event); out:/* Again, don't let gcc optimize things here */
@@ -1458,7 +1477,7 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)save_stack_trace_user (&trace);if (!filter_check_discard (call, entry, buffer, event)) -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event); out_drop_count:__this_cpu_dec (user_stack_count);
@@ -1653,7 +1672,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)memcpy (entry->buf, tbuffer,sizeof (u32) * len);if (!filter_check_discard (call, entry, buffer, event)) { -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event);ftrace_trace_stack (buffer, flags,6 , pc); }
@@ -1724,7 +1743,7 @@ int trace_array_vprintk(struct trace_array *tr,memcpy (&entry->buf, tbuffer, len); entry->buf[len] ='\0' ;if (!filter_check_discard (call, entry, buffer, event)) { -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event);ftrace_trace_stack (buffer, flags,6 , pc); } out:
@@ -3993,7 +4012,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, }else entry->buf[cnt] ='\0' ; -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event); written = cnt;
kernel/trace/trace.h +3 -0
@@ -359,6 +359,9 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,struct trace_entry *trace_find_next_entry (struct trace_iterator *iter,int *ent_cpu,u64 *ent_ts); +void __buffer_unlock_commit (struct ring_buffer *buffer, +struct ring_buffer_event *event); +int trace_empty (struct trace_iterator *iter);void *trace_find_next_entry_inc (struct trace_iterator *iter);
kernel/trace/trace_branch.c +1 -1
@@ -77,7 +77,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect) entry->correct = val == expect;if (!filter_check_discard (call, entry, buffer, event)) -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event); out:atomic_dec (&tr->data[cpu]->disabled);
kernel/trace/trace_functions_graph.c +2 -2
@@ -223,7 +223,7 @@ int __trace_graph_entry(struct trace_array *tr, entry =ring_buffer_event_data (event); entry->graph_ent = *trace;if (!filter_current_check_discard (buffer, call, entry, event)) -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event);return 1 ; }
@@ -327,7 +327,7 @@ void __trace_graph_return(struct trace_array *tr, entry =ring_buffer_event_data (event); entry->ret = *trace;if (!filter_current_check_discard (buffer, call, entry, event)) -ring_buffer_unlock_commit (buffer, event); +__buffer_unlock_commit (buffer, event); }void trace_graph_return (struct ftrace_graph_ret *trace)
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 9/22 tracing: Trivial cleanup
In reply to Steven RostedtFrom: David Sharp <[email protected]>
Remove ftrace_format_syscall() declaration; it is neither defined nor used. Also update a comment and formatting.
--- include/trace/syscall.h | 2 -- kernel/trace/ring_buffer.c | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-)
include/trace/syscall.h +0 -2
@@ -39,8 +39,6 @@ extern int reg_event_syscall_enter(struct ftrace_event_call *call);extern void unreg_event_syscall_enter (struct ftrace_event_call *call);extern int reg_event_syscall_exit (struct ftrace_event_call *call);extern void unreg_event_syscall_exit (struct ftrace_event_call *call); -extern int -ftrace_format_syscall (struct ftrace_event_call *call,struct trace_seq *s);enum print_line_t print_syscall_enter (struct trace_iterator *iter,int flags,struct trace_event *event); enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags,
kernel/trace/ring_buffer.c +3 -3
@@ -1821,7 +1821,7 @@ rb_add_time_stamp(struct ring_buffer_event *event, u64 delta) }/** -* ring_buffer_update_event - update event type and data +* rb_update_event - update event type and data * @event: the even to update * @type: the type of event * @length: the size of the event field in the ring buffer
@@ -2723,8 +2723,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_discard_commit);* and not the length of the event which would hold the header. */ int ring_buffer_write (struct ring_buffer *buffer, -unsigned long length, -void *data) +unsigned long length, +void *data) {struct ring_buffer_per_cpu *cpu_buffer;struct ring_buffer_event *event;
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 10/22 tracing: Cleanup unnecessary function declarations
In reply to Steven RostedtFrom: Vaibhav Nagarnaik <[email protected]>
The functions defined in include/trace/syscalls.h are not used directly since struct ftrace_event_class was introduced. Remove them from the header file and rearrange the ftrace_event_class declarations in trace_syscalls.c.
--- include/trace/syscall.h | 21 -------------- kernel/trace/trace_syscalls.c | 61 ++++++++++++++++++++--------------------- 2 files changed, 29 insertions(+), 53 deletions(-)
include/trace/syscall.h +0 -21
@@ -31,25 +31,4 @@ struct syscall_metadata { struct ftrace_event_call *exit_event; }; -#ifdef CONFIG_FTRACE_SYSCALLS -extern unsigned long arch_syscall_addr (int nr); -extern int init_syscall_trace (struct ftrace_event_call *call); - -extern int reg_event_syscall_enter (struct ftrace_event_call *call); -extern void unreg_event_syscall_enter (struct ftrace_event_call *call); -extern int reg_event_syscall_exit (struct ftrace_event_call *call); -extern void unreg_event_syscall_exit (struct ftrace_event_call *call); -enum print_line_t print_syscall_enter (struct trace_iterator *iter,int flags, -struct trace_event *event); -enum print_line_t print_syscall_exit (struct trace_iterator *iter,int flags, -struct trace_event *event); -#endif - -#ifdef CONFIG_PERF_EVENTS -int perf_sysenter_enable (struct ftrace_event_call *call); -void perf_sysenter_disable (struct ftrace_event_call *call); -int perf_sysexit_enable (struct ftrace_event_call *call); -void perf_sysexit_disable (struct ftrace_event_call *call); -#endif -#endif /* _TRACE_SYSCALL_H */
kernel/trace/trace_syscalls.c +29 -32
109 lines not on this page · raw message
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 11/22 linux/kernel.h: Remove duplicate trace_printk declaration
In reply to Steven RostedtFrom: Michal Hocko <[email protected]>
!CONFIG_TRACING both declares and defines (empty) trace_printk. The first one is not redundant so it can be removed.
--- include/linux/kernel.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
include/linux/kernel.h +2 -5
@@ -527,9 +527,6 @@ __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);extern void ftrace_dump (enum ftrace_dump_mode oops_dump_mode);#else -static inline __printf(1, 2) -int trace_printk(const char *fmt, ...); -static inline void tracing_start (void ) { }static inline void tracing_stop (void ) { }static inline void ftrace_off_permanent (void ) { }
@@ -539,8 +536,8 @@ static inline void tracing_on(void) { }static inline void tracing_off (void ) { }static inline int tracing_is_on (void ) {return 0 ; } -static inline int -trace_printk (const char *fmt, ...) +static inline __printf(1, 2) +int trace_printk(const char *fmt, ...) {return 0 ; }
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 12/22 tracing,x86: Add a TSC trace_clock
In reply to Steven RostedtFrom: David Sharp <[email protected]>
In order to promote interoperability between userspace tracers and ftrace, add a trace_clock that reports raw TSC values which will then be recorded in the ring buffer. Userspace tracers that also record TSCs are then on exactly the same time base as the kernel and events can be unambiguously interlaced.
Tested: Enabled a tracepoint and the "tsc" trace_clock and saw very large timestamp values.
v2:
Move arch-specific bits out of generic code.
v3:
Rename "x86-tsc", cleanups
v7:
Generic arch bits in Kbuild.
Google-Bug-Id: 6980623
--- arch/alpha/include/asm/Kbuild | 1 + arch/arm/include/asm/Kbuild | 1 + arch/arm64/include/asm/Kbuild | 1 + arch/avr32/include/asm/Kbuild | 1 + arch/blackfin/include/asm/Kbuild | 1 + arch/c6x/include/asm/Kbuild | 1 + arch/cris/include/asm/Kbuild | 1 + arch/frv/include/asm/Kbuild | 1 + arch/h8300/include/asm/Kbuild | 1 + arch/hexagon/include/asm/Kbuild | 1 + arch/ia64/include/asm/Kbuild | 1 + arch/m32r/include/asm/Kbuild | 1 + arch/m68k/include/asm/Kbuild | 1 + arch/microblaze/include/asm/Kbuild | 1 + arch/mips/include/asm/Kbuild | 1 + arch/mn10300/include/asm/Kbuild | 1 + arch/openrisc/include/asm/Kbuild | 1 + arch/parisc/include/asm/Kbuild | 2 +- arch/powerpc/include/asm/Kbuild | 1 + arch/s390/include/asm/Kbuild | 1 + arch/score/include/asm/Kbuild | 1 + arch/sh/include/asm/Kbuild | 1 + arch/sparc/include/asm/Kbuild | 1 + arch/tile/include/asm/Kbuild | 1 + arch/um/include/asm/Kbuild | 1 + arch/unicore32/include/asm/Kbuild | 1 + arch/x86/include/asm/trace_clock.h | 16 ++++++++++++++++ arch/x86/kernel/Makefile | 1 + arch/x86/kernel/trace_clock.c | 21 +++++++++++++++++++++ arch/xtensa/include/asm/Kbuild | 1 + include/asm-generic/trace_clock.h | 16 ++++++++++++++++ include/linux/trace_clock.h | 2 ++ kernel/trace/trace.c | 1 + 33 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/asm/trace_clock.h create mode 100644 arch/x86/kernel/trace_clock.c create mode 100644 include/asm-generic/trace_clock.h
arch/alpha/include/asm/Kbuild +1 -0
@@ -11,3 +11,4 @@ header-y += reg.h header-y += regdef.h header-y += sysinfo.h generic-y += exec.h +generic-y += trace_clock.h
arch/arm/include/asm/Kbuild +1 -0
@@ -31,5 +31,6 @@ generic-y += sockios.h generic-y += termbits.h generic-y += termios.h generic-y += timex.h +generic-y += trace_clock.h generic-y += types.h generic-y += unaligned.h
arch/arm64/include/asm/Kbuild +1 -0
@@ -43,6 +43,7 @@ generic-y += swab.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += unaligned.h generic-y += user.h
arch/avr32/include/asm/Kbuild +1 -0
@@ -1,3 +1,4 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += trace_clock.h
arch/blackfin/include/asm/Kbuild +1 -0
@@ -38,6 +38,7 @@ generic-y += statfs.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += unaligned.h
arch/c6x/include/asm/Kbuild +1 -0
@@ -49,6 +49,7 @@ generic-y += termbits.h generic-y += termios.h generic-y += tlbflush.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += user.h
arch/cris/include/asm/Kbuild +1 -0
@@ -11,3 +11,4 @@ header-y += sync_serial.h generic-y += clkdev.h generic-y += exec.h generic-y += module.h +generic-y += trace_clock.h
arch/frv/include/asm/Kbuild +1 -0
@@ -1,3 +1,4 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += trace_clock.h
arch/h8300/include/asm/Kbuild +1 -0
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm generic-y += clkdev.h generic-y += exec.h generic-y += module.h +generic-y += trace_clock.h
arch/hexagon/include/asm/Kbuild +1 -0
@@ -48,6 +48,7 @@ generic-y += stat.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += unaligned.h
arch/ia64/include/asm/Kbuild +1 -0
@@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += kvm_para.h +generic-y += trace_clock.h
arch/m32r/include/asm/Kbuild +1 -0
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm generic-y += clkdev.h generic-y += exec.h generic-y += module.h +generic-y += trace_clock.h
arch/m68k/include/asm/Kbuild +1 -0
@@ -24,6 +24,7 @@ generic-y += sections.h generic-y += siginfo.h generic-y += statfs.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += word-at-a-time.h generic-y += xor.h
arch/microblaze/include/asm/Kbuild +1 -0
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm header-y += elf.h generic-y += clkdev.h generic-y += exec.h +generic-y += trace_clock.h
arch/mips/include/asm/Kbuild +1 -0
@@ -1 +1,2 @@ +generic-y += trace_clock.h # MIPS headers
arch/mn10300/include/asm/Kbuild +1 -0
@@ -1,3 +1,4 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += trace_clock.h
arch/openrisc/include/asm/Kbuild +1 -0
@@ -60,6 +60,7 @@ generic-y += swab.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += user.h
arch/parisc/include/asm/Kbuild +1 -1
@@ -2,4 +2,4 @@ generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \ segment.h topology.h vga.h device.h percpu.h hw_irq.h mutex.h \ div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \ - poll.h xor.h clkdev.h exec.h + poll.h xor.h clkdev.h exec.h trace_clock.h
arch/powerpc/include/asm/Kbuild +1 -0
@@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += rwsem.h +generic-y += trace_clock.h
arch/s390/include/asm/Kbuild +1 -0
@@ -1,3 +1,4 @@ generic-y += clkdev.h +generic-y += trace_clock.h
arch/score/include/asm/Kbuild +1 -0
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm header-y += generic-y += clkdev.h +generic-y += trace_clock.h
arch/sh/include/asm/Kbuild +1 -0
@@ -31,5 +31,6 @@ generic-y += socket.h generic-y += statfs.h generic-y += termbits.h generic-y += termios.h +generic-y += trace_clock.h generic-y += ucontext.h generic-y += xor.h
arch/sparc/include/asm/Kbuild +1 -0
@@ -8,4 +8,5 @@ generic-y += local64.h generic-y += irq_regs.h generic-y += local.h generic-y += module.h +generic-y += trace_clock.h generic-y += word-at-a-time.h
arch/tile/include/asm/Kbuild +1 -0
@@ -34,5 +34,6 @@ generic-y += sockios.h generic-y += statfs.h generic-y += termbits.h generic-y += termios.h +generic-y += trace_clock.h generic-y += types.h generic-y += xor.h
arch/um/include/asm/Kbuild +1 -0
@@ -2,3 +2,4 @@ generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h generic-y += switch_to.h clkdev.h +generic-y += trace_clock.h
arch/unicore32/include/asm/Kbuild +1 -0
@@ -54,6 +54,7 @@ generic-y += syscalls.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += unaligned.h
arch/x86/include/asm/trace_clock.h new file +16 -0
@@ -0,0 +1,16 @@ +#ifndef _ASM_X86_TRACE_CLOCK_H +#define _ASM_X86_TRACE_CLOCK_H + +#include <linux/compiler.h> +#include <linux/types.h> + +#ifdef CONFIG_X86_TSC + +extern u64 notrace trace_clock_x86_tsc(void); + +# define ARCH_TRACE_CLOCKS \ + { trace_clock_x86_tsc, "x86-tsc" }, + +#endif + +#endif /* _ASM_X86_TRACE_CLOCK_H */
arch/x86/kernel/Makefile +1 -0
@@ -61,6 +61,7 @@ obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o +obj-$(CONFIG_X86_TSC) += trace_clock.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
arch/x86/kernel/trace_clock.c new file +21 -0
@@ -0,0 +1,21 @@ +/* +* X86 trace clocks +*/ +#include <asm/trace_clock.h> +#include <asm/barrier.h> +#include <asm/msr.h> + +/* +* trace_clock_x86_tsc(): A clock that is just the cycle counter. +* +* Unlike the other clocks, this is not in nanoseconds. +*/ +u64 notrace trace_clock_x86_tsc(void) +{ +u64 ret; + +rdtsc_barrier (); +rdtscll (ret); + +return ret; +}
arch/xtensa/include/asm/Kbuild +1 -0
@@ -25,4 +25,5 @@ generic-y += siginfo.h generic-y += statfs.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += xor.h
include/asm-generic/trace_clock.h new file +16 -0
@@ -0,0 +1,16 @@ +#ifndef _ASM_GENERIC_TRACE_CLOCK_H +#define _ASM_GENERIC_TRACE_CLOCK_H +/* +* Arch-specific trace clocks. +*/ + +/* +* Additional trace clocks added to the trace_clocks +* array in kernel/trace/trace.c +* None if the architecture has not defined it. +*/ +#ifndef ARCH_TRACE_CLOCKS +# define ARCH_TRACE_CLOCKS +#endif + +#endif /* _ASM_GENERIC_TRACE_CLOCK_H */
include/linux/trace_clock.h +2 -0
@@ -12,6 +12,8 @@#include <linux/compiler.h> #include <linux/types.h> +#include <asm/trace_clock.h> + extern u64 notrace trace_clock_local(void); extern u64 notrace trace_clock(void); extern u64 notrace trace_clock_global(void);
kernel/trace/trace.c +1 -0
@@ -488,6 +488,7 @@ static struct { { trace_clock_local, "local" }, { trace_clock_global, "global" }, { trace_clock_counter, "counter" }, + ARCH_TRACE_CLOCKS };int trace_clock_id;
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 13/22 tracing: Reset ring buffer when changing trace_clocks
In reply to Steven RostedtFrom: David Sharp <[email protected]>
Because the "tsc" clock isn't in nanoseconds, the ring buffer must be reset when changing clocks so that incomparable timestamps don't end up in the same trace.
Tested: Confirmed switching clocks resets the trace buffer.
Google-Bug-Id: 6980623
--- kernel/trace/trace.c | 8 ++++++++ 1 file changed, 8 insertions(+)
kernel/trace/trace.c +8 -0
@@ -4074,6 +4074,14 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,if (max_tr.buffer)ring_buffer_set_clock (max_tr.buffer, trace_clocks[i].func); +/* +* New clock may not be consistent with the previous clock. +* Reset the buffer so that it doesn't have incomparable timestamps. +*/ +tracing_reset_online_cpus (&global_trace); +if (max_tr.buffer) +tracing_reset_online_cpus (&max_tr); +mutex_unlock (&trace_types_lock); *fpos += cnt;
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 14/22 tracing: Format non-nanosec times from tsc clock without a decimal point.
In reply to Steven RostedtFrom: David Sharp <[email protected]>
With the addition of the "tsc" clock, formatting timestamps to look like fractional seconds is misleading. Mark clocks as either in nanoseconds or not, and format non-nanosecond timestamps as decimal integers.
Tested:
$ cd /sys/kernel/debug/tracing/
$ cat trace_clock
[local] global tsc
$ echo sched_switch > set_event
$ echo 1 > tracing_enabled ; sleep 0.0005 ; echo 0 > tracing_enabled
$ cat trace
<idle>-0 [000] 6330.555552: sched_switch: prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=bash next_pid=29964 next_prio=120
sleep-29964 [000] 6330.555628: sched_switch: prev_comm=bash prev_pid=29964 prev_prio=120 prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120
...
$ echo 1 > options/latency-format
$ cat trace
<idle>-0 0 4104553247us+: sched_switch: prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=bash next_pid=29964 next_prio=120
sleep-29964 0 4104553322us+: sched_switch: prev_comm=bash prev_pid=29964 prev_prio=120 prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120
...
$ echo tsc > trace_clock
$ cat trace
$ echo 1 > tracing_enabled ; sleep 0.0005 ; echo 0 > tracing_enabled
$ echo 0 > options/latency-format
$ cat trace
<idle>-0 [000] 16490053398357: sched_switch: prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=bash next_pid=31128 next_prio=120
sleep-31128 [000] 16490053588518: sched_switch: prev_comm=bash prev_pid=31128 prev_prio=120 prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120
...
echo 1 > options/latency-format
$ cat trace
<idle>-0 0 91557653238+: sched_switch: prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=bash next_pid=31128 next_prio=120
sleep-31128 0 91557843399+: sched_switch: prev_comm=bash prev_pid=31128 prev_prio=120 prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120
...v2:
Move arch-specific bits out of generic code.
v4:
Fix x86_32 build due to 64-bit division.
Google-Bug-Id: 6980623
--- arch/x86/include/asm/trace_clock.h | 2 +- include/linux/ftrace_event.h | 6 +++ kernel/trace/trace.c | 15 +++++-- kernel/trace/trace.h | 4 -- kernel/trace/trace_output.c | 80 +++++++++++++++++++++++++----------- 5 files changed, 74 insertions(+), 33 deletions(-)
arch/x86/include/asm/trace_clock.h +1 -1
@@ -9,7 +9,7 @@ extern u64 notrace trace_clock_x86_tsc(void);# define ARCH_TRACE_CLOCKS \ - { trace_clock_x86_tsc, "x86-tsc" }, + { trace_clock_x86_tsc, "x86-tsc", .in_ns = 0 },#endif
include/linux/ftrace_event.h +6 -0
@@ -86,6 +86,12 @@ struct trace_iterator {cpumask_var_t started; }; +enum trace_iter_flags { +TRACE_FILE_LAT_FMT =1 , +TRACE_FILE_ANNOTATE =2 , +TRACE_FILE_TIME_IN_NS =4 , +}; +struct trace_event ;
kernel/trace/trace.c +12 -3
@@ -484,10 +484,11 @@ static const char *trace_options[] = {static struct {u64 (*func)(void );const char *name; +int in_ns;/* is this clock in nanoseconds? */ } trace_clocks[] = { - { trace_clock_local,"local" }, - { trace_clock_global,"global" }, - { trace_clock_counter,"counter" }, + { trace_clock_local,"local" ,1 }, + { trace_clock_global,"global" ,1 }, + { trace_clock_counter,"counter" ,0 },ARCH_TRACE_CLOCKS };
@@ -2477,6 +2478,10 @@ __tracing_open(struct inode *inode, struct file *file)if (ring_buffer_overruns (iter->tr->buffer)) iter->iter_flags |=TRACE_FILE_ANNOTATE ; +/* Output in nanoseconds only if we are using a clock in nanoseconds. */ +if (trace_clocks[trace_clock_id].in_ns) + iter->iter_flags |=TRACE_FILE_TIME_IN_NS ; +/* stop the trace while dumping */ tracing_stop ();
@@ -3383,6 +3388,10 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)if (trace_flags &TRACE_ITER_LATENCY_FMT ) iter->iter_flags |=TRACE_FILE_LAT_FMT ; +/* Output in nanoseconds only if we are using a clock in nanoseconds. */ +if (trace_clocks[trace_clock_id].in_ns) + iter->iter_flags |=TRACE_FILE_TIME_IN_NS ; + iter->cpu_file = cpu_file; iter->tr = &global_trace;mutex_init (&iter->mutex);
kernel/trace/trace.h +0 -4
@@ -412,10 +412,6 @@ void tracing_start_sched_switch_record(void);int register_tracer (struct tracer *type);void unregister_tracer (struct tracer *type);int is_tracing_stopped (void ); -enum trace_file_type { -TRACE_FILE_LAT_FMT =1 , -TRACE_FILE_ANNOTATE =2 , -};extern cpumask_var_t __read_mostly tracing_buffer_mask;
kernel/trace/trace_output.c +55 -25
123 lines not on this page · raw message
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 15/22 ring-buffer: Change unsigned long type of ring_buffer_oldest_event_ts() to u64
In reply to Steven RostedtFrom: Yoshihiro YUNOMAE <[email protected]>
ring_buffer_oldest_event_ts() should return a value of u64 type, because ring_buffer_per_cpu->buffer_page->buffer_data_page->time_stamp is u64 type.
--- include/linux/ring_buffer.h | 2 +- kernel/trace/ring_buffer.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
include/linux/ring_buffer.h +1 -1
@@ -159,7 +159,7 @@ int ring_buffer_record_is_on(struct ring_buffer *buffer);void ring_buffer_record_disable_cpu (struct ring_buffer *buffer,int cpu);void ring_buffer_record_enable_cpu (struct ring_buffer *buffer,int cpu); -unsigned long ring_buffer_oldest_event_ts (struct ring_buffer *buffer,int cpu); +u64 ring_buffer_oldest_event_ts (struct ring_buffer *buffer,int cpu);unsigned long ring_buffer_bytes_cpu (struct ring_buffer *buffer,int cpu);unsigned long ring_buffer_entries (struct ring_buffer *buffer);unsigned long ring_buffer_overruns (struct ring_buffer *buffer);
kernel/trace/ring_buffer.c +2 -2
@@ -2932,12 +2932,12 @@ rb_num_of_entries(struct ring_buffer_per_cpu *cpu_buffer)* @buffer: The ring buffer * @cpu: The per CPU buffer to read from. */ -unsigned long ring_buffer_oldest_event_ts (struct ring_buffer *buffer,int cpu) +u64 ring_buffer_oldest_event_ts (struct ring_buffer *buffer,int cpu) {unsigned long flags;struct ring_buffer_per_cpu *cpu_buffer;struct buffer_page *bpage; -unsigned long ret; +u64 ret;if (!cpumask_test_cpu (cpu, buffer->cpumask))return 0 ;
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 16/22 tracing: Show raw time stamp on stats per cpu using counter or tsc mode for trace_clock
In reply to Steven RostedtFrom: Yoshihiro YUNOMAE <[email protected]>
Show raw time stamp values for stats per cpu if you choose counter or tsc mode for trace_clock. Although a unit of tracing time stamp is nsec in local or global mode, the units in counter and TSC mode are tracing counter and cycles respectively.
--- kernel/trace/trace.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
kernel/trace/trace.c +17 -6
@@ -4452,13 +4452,24 @@ tracing_stats_read(struct file *filp, char __user *ubuf, cnt =ring_buffer_bytes_cpu (tr->buffer, cpu);trace_seq_printf (s,"bytes: %ld\n" , cnt); - t =ns2usecs (ring_buffer_oldest_event_ts (tr->buffer, cpu)); - usec_rem =do_div (t,USEC_PER_SEC ); -trace_seq_printf (s,"oldest event ts: %5llu.%06lu\n" , t, usec_rem); +if (trace_clocks[trace_clock_id].in_ns) { +/* local or global for trace_clock */ + t =ns2usecs (ring_buffer_oldest_event_ts (tr->buffer, cpu)); + usec_rem =do_div (t,USEC_PER_SEC ); +trace_seq_printf (s,"oldest event ts: %5llu.%06lu\n" , + t, usec_rem); + + t =ns2usecs (ring_buffer_time_stamp (tr->buffer, cpu)); + usec_rem =do_div (t,USEC_PER_SEC ); +trace_seq_printf (s,"now ts: %5llu.%06lu\n" , t, usec_rem); + }else { +/* counter or tsc mode for trace_clock */ +trace_seq_printf (s,"oldest event ts: %llu\n" , +ring_buffer_oldest_event_ts (tr->buffer, cpu)); - t =ns2usecs (ring_buffer_time_stamp (tr->buffer, cpu)); - usec_rem =do_div (t,USEC_PER_SEC ); -trace_seq_printf (s,"now ts: %5llu.%06lu\n" , t, usec_rem); +trace_seq_printf (s,"now ts: %llu\n" , +ring_buffer_time_stamp (tr->buffer, cpu)); + } cnt =ring_buffer_dropped_events_cpu (tr->buffer, cpu);trace_seq_printf (s,"dropped events: %ld\n" , cnt);
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 17/22 tracing: Separate open function from set_event and available_events
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The open function used by available_events is the same as set_event even though it uses different seq functions. This causes a side effect of writing into available_events clearing all events, even though available_events is suppose to be read only.
There's no reason to keep a single function for just the open and have both use different functions for everything else. It is a little confusing and causes strange behavior. Just have each have their own function.
--- kernel/trace/trace_events.c | 46 +++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 19 deletions(-)
kernel/trace/trace_events.c +27 -19
@@ -491,19 +491,6 @@ static void t_stop(struct seq_file *m, void *p)mutex_unlock (&event_mutex); } -static int -ftrace_event_seq_open (struct inode *inode,struct file *file) -{ -const struct seq_operations *seq_ops; - -if ((file->f_mode &FMODE_WRITE ) && - (file->f_flags &O_TRUNC )) -ftrace_clear_events (); - - seq_ops = inode->i_private; -return seq_open (file, seq_ops); -} -static ssize_t event_enable_read (struct file *filp,char __user *ubuf,size_t cnt,loff_t *ppos)
@@ -980,6 +967,9 @@ show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)return r; } +static int ftrace_event_avail_open (struct inode *inode,struct file *file); +static int ftrace_event_set_open (struct inode *inode,struct file *file); +static const struct seq_operations show_event_seq_ops = { .start = t_start, .next = t_next,
@@ -995,14 +985,14 @@ static const struct seq_operations show_set_event_seq_ops = { };static const struct file_operations ftrace_avail_fops = { - .open = ftrace_event_seq_open, + .open = ftrace_event_avail_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, };static const struct file_operations ftrace_set_event_fops = { - .open = ftrace_event_seq_open, + .open = ftrace_event_set_open, .read = seq_read, .write = ftrace_event_write, .llseek = seq_lseek,
@@ -1078,6 +1068,26 @@ static struct dentry *event_trace_events_dir(void)return d_events; } +static int +ftrace_event_avail_open (struct inode *inode,struct file *file) +{ +const struct seq_operations *seq_ops = &show_event_seq_ops; + +return seq_open (file, seq_ops); +} + +static int +ftrace_event_set_open (struct inode *inode,struct file *file) +{ +const struct seq_operations *seq_ops = &show_set_event_seq_ops; + +if ((file->f_mode &FMODE_WRITE ) && + (file->f_flags &O_TRUNC )) +ftrace_clear_events (); + +return seq_open (file, seq_ops); +} +static struct dentry *event_subsystem_dir (const char *name,struct dentry *d_events) {
@@ -1508,15 +1518,13 @@ static __init int event_trace_init(void)return 0 ; entry =debugfs_create_file ("available_events" ,0444 , d_tracer, - (void *)&show_event_seq_ops, - &ftrace_avail_fops); +NULL , &ftrace_avail_fops);if (!entry)pr_warning ("Could not create debugfs " "'available_events' entry\n" ); entry =debugfs_create_file ("set_event" ,0644 , d_tracer, - (void *)&show_set_event_seq_ops, - &ftrace_set_event_fops); +NULL , &ftrace_set_event_fops);if (!entry)pr_warning ("Could not create debugfs " "'set_event' entry\n" );
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 18/22 tracing: Remove unused function unregister_tracer()
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The function register_tracer() is only used by kernel core code, that never needs to remove the tracer. As trace_events have become the main way to add new tracing to the kernel, the need to unregister a tracer has diminished. Remove the unused function unregister_tracer(). If a need arises where we need it, then we can always add it back.
--- kernel/trace/trace.c | 26 -------------------------- kernel/trace/trace.h | 1 - 2 files changed, 27 deletions(-)
kernel/trace/trace.c +0 -26
@@ -884,32 +884,6 @@ int register_tracer(struct tracer *type)return ret; } -void unregister_tracer (struct tracer *type) -{ -struct tracer **t; - -mutex_lock (&trace_types_lock); -for (t = &trace_types; *t; t = &(*t)->next) { -if (*t == type) - goto found; - } -pr_info ("Tracer %s not registered\n" , type->name); - goto out; - - found: - *t = (*t)->next; - -if (type == current_trace && tracer_enabled) { - tracer_enabled =0 ; -tracing_stop (); -if (current_trace->stop) - current_trace->stop (&global_trace); - current_trace = &nop_trace; - } -out: -mutex_unlock (&trace_types_lock); -} -void tracing_reset (struct trace_array *tr,int cpu) {struct ring_buffer *buffer = tr->buffer;
kernel/trace/trace.h +0 -1
@@ -410,7 +410,6 @@ void tracing_sched_switch_assign_trace(struct trace_array *tr);void tracing_stop_sched_switch_record (void );void tracing_start_sched_switch_record (void );int register_tracer (struct tracer *type); -void unregister_tracer (struct tracer *type);int is_tracing_stopped (void );extern cpumask_var_t __read_mostly tracing_buffer_mask;
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 19/22 tracing: Make tracing_enabled be equal to tracing_on
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The tracing_enabled file has been deprecated as it never was able to serve its purpose well. The tracing_on file has taken over. Instead of having code to keep tracing_enabled, have the tracing_enabled file just set tracing_on, and remove the tracing_enabled variable.
This allows us to remove the tracing_enabled file. The reason that the remove is in a different change set and not removed here is in case we find some lonely userspace tool that requires the file to exist. Then the removal patch will get reverted, but this one will not.
--- kernel/trace/trace.c | 79 +++-------------------------------------- kernel/trace/trace_selftest.c | 12 ------- 2 files changed, 5 insertions(+), 86 deletions(-)
kernel/trace/trace.c +5 -74
@@ -205,20 +205,9 @@ static struct trace_array max_tr; static DEFINE_PER_CPU(struct trace_array_cpu, max_tr_data); -/* tracer_enabled is used to toggle activation of a tracer */ -static int tracer_enabled =1 ; - -/** -* tracing_is_enabled - return tracer_enabled status -* -* This function is used by other tracers to know the status -* of the tracer_enabled flag. Tracers may use this function -* to know if it should enable their features when starting -* up. See irqsoff tracer for an example (start_irqsoff_tracer). -*/ int tracing_is_enabled (void ) { -return tracer_enabled; +return tracing_is_on (); }/*
@@ -1114,8 +1103,7 @@ void trace_find_cmdline(int pid, char comm[])void tracing_record_cmdline (struct task_struct *tsk) { -if (atomic_read (&trace_record_cmdline_disabled) || !tracer_enabled || - !tracing_is_on ()) +if (atomic_read (&trace_record_cmdline_disabled) || !tracing_is_on ())return ;if (!__this_cpu_read (trace_cmdline_save))
@@ -2973,56 +2961,6 @@ static const struct file_operations tracing_saved_cmdlines_fops = { };static ssize_t -tracing_ctrl_read (struct file *filp,char __user *ubuf, -size_t cnt,loff_t *ppos) -{ -char buf[64 ]; -int r; - - r =sprintf (buf,"%u\n" , tracer_enabled); -return simple_read_from_buffer (ubuf, cnt, ppos, buf, r); -} - -static ssize_t -tracing_ctrl_write (struct file *filp,const char __user *ubuf, -size_t cnt,loff_t *ppos) -{ -struct trace_array *tr = filp->private_data; -unsigned long val; -int ret; - - ret =kstrtoul_from_user (ubuf, cnt,10 , &val); -if (ret) -return ret; - - val = !!val; - -mutex_lock (&trace_types_lock); -if (tracer_enabled ^ val) { - -/* Only need to warn if this is used to change the state */ -WARN_ONCE (1 ,"tracing_enabled is deprecated. Use tracing_on" ); - -if (val) { - tracer_enabled =1 ; -if (current_trace->start) - current_trace->start (tr); -tracing_start (); - }else { - tracer_enabled =0 ; -tracing_stop (); -if (current_trace->stop) - current_trace->stop (tr); - } - } -mutex_unlock (&trace_types_lock); - - *ppos += cnt; - -return cnt; -} - -static ssize_t tracing_set_trace_read (struct file *filp,char __user *ubuf,size_t cnt,loff_t *ppos) {
@@ -3479,7 +3417,7 @@ static int tracing_wait_pipe(struct file *filp)return -EINTR ;/* -* We block until we read something and tracing is disabled. +* We block until we read something and tracing is enabled. * We still block if tracing is disabled, but we have never * read anything. This allows a user to cat this file, and * then enable tracing. But after we have read something,
@@ -3487,7 +3425,7 @@ static int tracing_wait_pipe(struct file *filp)* * iter->pos will be 0 if we haven't read anything. */ -if (!tracer_enabled && iter->pos) +if (tracing_is_enabled () && iter->pos)break ; }
@@ -4086,13 +4024,6 @@ static const struct file_operations tracing_max_lat_fops = { .llseek = generic_file_llseek, }; -static const struct file_operations tracing_ctrl_fops = { - .open = tracing_open_generic, - .read = tracing_ctrl_read, - .write = tracing_ctrl_write, - .llseek = generic_file_llseek, -}; -static const struct file_operations set_tracer_fops = { .open = tracing_open_generic, .read = tracing_set_trace_read,
@@ -4879,7 +4810,7 @@ static __init int tracer_init_debugfs(void) d_tracer =tracing_init_dentry ();trace_create_file ("tracing_enabled" ,0644 , d_tracer, - &global_trace, &tracing_ctrl_fops); + &global_trace, &rb_simple_fops);trace_create_file ("trace_options" ,0644 , d_tracer,NULL , &tracing_iter_fops);
kernel/trace/trace_selftest.c +0 -12
@@ -320,7 +320,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, int (*func)(void)) {int save_ftrace_enabled = ftrace_enabled; -int save_tracer_enabled = tracer_enabled;unsigned long count;char *func_name;int ret;
@@ -331,7 +330,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,/* enable tracing, and record the filter function */ ftrace_enabled =1 ; - tracer_enabled =1 ;/* passed in by parameter to fool gcc from optimizing */ func ();
@@ -395,7 +393,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, out: ftrace_enabled = save_ftrace_enabled; - tracer_enabled = save_tracer_enabled;/* Enable tracing on all functions again */ ftrace_set_global_filter (NULL ,0 ,1 );
@@ -452,7 +449,6 @@ static inttrace_selftest_function_recursion (void) {int save_ftrace_enabled = ftrace_enabled; -int save_tracer_enabled = tracer_enabled;char *func_name;int len;int ret;
@@ -465,7 +461,6 @@ trace_selftest_function_recursion(void)/* enable tracing, and record the filter function */ ftrace_enabled =1 ; - tracer_enabled =1 ;/* Handle PPC64 '.' name */ func_name ="*" __stringify(DYN_FTRACE_TEST_NAME );
@@ -534,7 +529,6 @@ trace_selftest_function_recursion(void) ret =0 ; out: ftrace_enabled = save_ftrace_enabled; - tracer_enabled = save_tracer_enabled;return ret; }
@@ -569,7 +563,6 @@ static inttrace_selftest_function_regs (void) {int save_ftrace_enabled = ftrace_enabled; -int save_tracer_enabled = tracer_enabled;char *func_name;int len;int ret;
@@ -586,7 +579,6 @@ trace_selftest_function_regs(void)/* enable tracing, and record the filter function */ ftrace_enabled =1 ; - tracer_enabled =1 ;/* Handle PPC64 '.' name */ func_name ="*" __stringify(DYN_FTRACE_TEST_NAME );
@@ -648,7 +640,6 @@ trace_selftest_function_regs(void) ret =0 ; out: ftrace_enabled = save_ftrace_enabled; - tracer_enabled = save_tracer_enabled;return ret; }
@@ -662,7 +653,6 @@ int trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) { int save_ftrace_enabled = ftrace_enabled; -int save_tracer_enabled = tracer_enabled;unsigned long count;int ret;
@@ -671,7 +661,6 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)/* start the tracing */ ftrace_enabled =1 ; - tracer_enabled =1 ; ret =tracer_init (trace, tr);if (ret) {
@@ -708,7 +697,6 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) ret =trace_selftest_function_regs (); out: ftrace_enabled = save_ftrace_enabled; - tracer_enabled = save_tracer_enabled;/* kill ftrace totally if we failed */ if (ret)
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 20/22 tracing: Remove deprecated tracing_enabled file
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The tracing_enabled file was used as a quick way to stop tracers, and try to bring down overhead for things like the latency tracers (irqsoff, wakeup, etc). But it didn't work that well.
The tracing_on file was created as a really fast way to stop recording into the ftrace ring buffer and can interact with the kernel. That is a tracing_off() call in the kernel can disable recording of events, and then from userspace one could echo 1 into the tracing_on file to continue it. The tracing_enabled function did too much to allow for this.
The tracing_on has taken over as a way to start and stop tracing and the tracing_enabled file should not be used. But because of its existance, it still confuses people. Over a year ago the following commit was added:
commit 6752ab4a9c30d5411b2dfdb251a3f1cb18aae487
Author: Steven Rostedt <[email protected]>
Date: Tue Feb 8 13:54:06 2011 -0500
tracing: Deprecate tracing_enabled for tracing_on
This commit added a WARN_ON() if the tracing_enabled file's variable was changed. After this was added, only LatencyTop complained, and they soon fixed their tool as there was no reason that LatencyTop should touch this file as it was using the perf ring buffers which this file does not interact with. But since that time no one else has complained about this WARN_ON(). Thus it is safe to assume that this file is no longer needed. Time to get rid of it.
--- kernel/trace/trace.c | 3 --- 1 file changed, 3 deletions(-)
kernel/trace/trace.c +0 -3
@@ -4809,9 +4809,6 @@ static __init int tracer_init_debugfs(void) d_tracer =tracing_init_dentry (); -trace_create_file ("tracing_enabled" ,0644 , d_tracer, - &global_trace, &rb_simple_fops); -trace_create_file ("trace_options" ,0644 , d_tracer,NULL , &tracing_iter_fops);
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 21/22 tracing: Use irq_work for wake ups and remove *_nowake_*() functions
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Have the ring buffer commit function use the irq_work infrastructure to wake up any waiters waiting on the ring buffer for new data. The irq_work was created for such a purpose, where doing the actual wake up at the time of adding data is too dangerous, as an event or function trace may be in the midst of the work queue locks and cause deadlocks. The irq_work will either delay the action to the next timer interrupt, or trigger an IPI to itself forcing an interrupt to do the work (in a safe location).
With irq_work, all ring buffer commits can safely do wakeups, removing the need for the ring buffer commit "nowake" variants, which were used by events and function tracing. All commits can now safely use the normal commit, and the "nowake" variants can be removed.
--- include/linux/ftrace_event.h | 14 ++--- include/trace/ftrace.h | 3 +- kernel/trace/Kconfig | 1 + kernel/trace/trace.c | 121 +++++++++++++++++++++---------------- kernel/trace/trace.h | 5 -- kernel/trace/trace_events.c | 2 +- kernel/trace/trace_kprobe.c | 8 +-- kernel/trace/trace_sched_switch.c | 2 +- kernel/trace/trace_selftest.c | 1 + 9 files changed, 84 insertions(+), 73 deletions(-)
include/linux/ftrace_event.h +7 -7
@@ -133,13 +133,13 @@ trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer,void trace_current_buffer_unlock_commit (struct ring_buffer *buffer,struct ring_buffer_event *event,unsigned long flags,int pc); -void trace_nowake_buffer_unlock_commit (struct ring_buffer *buffer, -struct ring_buffer_event *event, -unsigned long flags,int pc); -void trace_nowake_buffer_unlock_commit_regs (struct ring_buffer *buffer, -struct ring_buffer_event *event, -unsigned long flags,int pc, -struct pt_regs *regs); +void trace_buffer_unlock_commit (struct ring_buffer *buffer, +struct ring_buffer_event *event, +unsigned long flags,int pc); +void trace_buffer_unlock_commit_regs (struct ring_buffer *buffer, +struct ring_buffer_event *event, +unsigned long flags,int pc, +struct pt_regs *regs);void trace_current_buffer_discard_commit (struct ring_buffer *buffer,struct ring_buffer_event *event);
include/trace/ftrace.h +1 -2
@@ -545,8 +545,7 @@ ftrace_raw_event_##call(void *__data, proto) \ { assign; } \ \if (!filter_current_check_discard (buffer, event_call, entry, event)) \ -trace_nowake_buffer_unlock_commit (buffer, \ - event, irq_flags, pc); \ +trace_buffer_unlock_commit (buffer, event, irq_flags, pc); \ }/* * The ftrace_test_probe is compiled out, it is only here as a build time check
kernel/trace/Kconfig +1 -0
@@ -119,6 +119,7 @@ config TRACING select BINARY_PRINTF select EVENT_TRACING select TRACE_CLOCK + select IRQ_WORK config GENERIC_TRACER bool
kernel/trace/trace.c +68 -53
204 lines not on this page · raw message
kernel/trace/trace.h +0 -5
@@ -327,7 +327,6 @@ trace_buffer_iter(struct trace_iterator *iter, int cpu)int tracer_init (struct tracer *t,struct trace_array *tr);int tracing_is_enabled (void ); -void trace_wake_up (void );void tracing_reset (struct trace_array *tr,int cpu);void tracing_reset_online_cpus (struct trace_array *tr);void tracing_reset_current (int cpu);
@@ -349,9 +348,6 @@ trace_buffer_lock_reserve(struct ring_buffer *buffer,unsigned long len, unsigned long flags, int pc); -void trace_buffer_unlock_commit (struct ring_buffer *buffer, -struct ring_buffer_event *event, -unsigned long flags,int pc);struct trace_entry *tracing_get_trace_entry (struct trace_array *tr,struct trace_array_cpu *data);
@@ -370,7 +366,6 @@ void trace_init_global_iter(struct trace_iterator *iter);void tracing_iter_reset (struct trace_iterator *iter,int cpu); -void default_wait_pipe (struct trace_iterator *iter);void poll_wait_pipe (struct trace_iterator *iter); void ftrace(struct trace_array *tr,
kernel/trace/trace_events.c +1 -1
@@ -1760,7 +1760,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip, entry->ip = ip; entry->parent_ip = parent_ip; -trace_nowake_buffer_unlock_commit (buffer, event, flags, pc); +trace_buffer_unlock_commit (buffer, event, flags, pc); out:atomic_dec (&per_cpu (ftrace_test_event_disable, cpu));
kernel/trace/trace_kprobe.c +4 -4
@@ -751,8 +751,8 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)store_trace_args (sizeof (*entry), tp, regs, (u8 *)&entry[1 ], dsize);if (!filter_current_check_discard (buffer, call, entry, event)) -trace_nowake_buffer_unlock_commit_regs (buffer, event, - irq_flags, pc, regs); +trace_buffer_unlock_commit_regs (buffer, event, + irq_flags, pc, regs); }/* Kretprobe handler */
@@ -784,8 +784,8 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,store_trace_args (sizeof (*entry), tp, regs, (u8 *)&entry[1 ], dsize);if (!filter_current_check_discard (buffer, call, entry, event)) -trace_nowake_buffer_unlock_commit_regs (buffer, event, - irq_flags, pc, regs); +trace_buffer_unlock_commit_regs (buffer, event, + irq_flags, pc, regs); }/* Event entry printers */
kernel/trace/trace_sched_switch.c +1 -1
@@ -102,7 +102,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->next_cpu =task_cpu (wakee);if (!filter_check_discard (call, entry, buffer, event)) -trace_nowake_buffer_unlock_commit (buffer, event, flags, pc); +trace_buffer_unlock_commit (buffer, event, flags, pc); } static void
kernel/trace/trace_selftest.c +1 -0
@@ -1094,6 +1094,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)tracing_stop ();/* check both trace buffers */ ret =trace_test_buffer (tr,NULL ); +printk ("ret = %d\n" , ret);if (!ret) ret =trace_test_buffer (&max_tr, &count);
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerPATCH 22/22 tracing: Add trace_options kernel command line parameter
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Add trace_options to the kernel command line parameter to be able to set options at early boot. For example, to enable stack dumps of events, add the following:
trace_options=stacktrace
This along with the trace_event option, you can get not only traces of the events but also the stack dumps with them.
--- Documentation/kernel-parameters.txt | 16 +++++++++++ kernel/trace/trace.c | 54 +++++++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 15 deletions(-)
Documentation/kernel-parameters.txt +16 -0
@@ -2859,6 +2859,22 @@ bytes respectively. Such letter suffixes can also be entirely omitted. to facilitate early boot debugging. See also Documentation/trace/events.txt + trace_options=[option-list] + [FTRACE] Enable or disable tracer options at boot. + The option-list is a comma delimited list of options + that can be enabled or disabled just as if you were + to echo the option name into + + /sys/kernel/debug/tracing/trace_options + + For example, to enable stacktrace option (to dump the + stack trace of each event), add to the command line: + + trace_options=stacktrace + + See also Documentation/trace/ftrace.txt "trace options" + section. + transparent_hugepage= [KNL] Format: [always|madvise|never]
kernel/trace/trace.c +39 -15
85 lines not on this page · raw message
Signature · 1 line
1.7.10.4
Steven Rostedt
maintainerQuoted 1 line · Steven Rostedt
Ingo,
Hold off on pulling this. Fengguang found some subtle bugs in David's patches and I'm going to rebase (again) without them. I don't want to hold up the rest of the patches for these few bugs.
I'll post a tip/perf/core-2 soon.
-- Steve
Quoted 110 lines
I've been focusing on -rt related things lately and let my tracing queue pile up on me. I've ran these through my own vigorous tests, and think they are ready for 3.8.
Please pull the latest tip/perf/core tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
tip/perf/coreHead SHA1:
9b194e6cb864506da693d26149370cb7272af99fDaniel Walter (1):
tracing: Replace strict_strto* with kstrto*David Sharp (4):
tracing: Trivial cleanup
tracing,x86: Add a TSCtrace_clock
tracing: Reset ring buffer when changingtrace_clocks
tracing: Format non-nanosec times from tsc clock without a decimal point.Hiraku Toyooka (1):
tracing: Change tracer's integer flags to boolMichal Hocko (1):
linux/kernel.h: Remove duplicatetrace_printkdeclarationSlava Pestov (1):
ring-buffer: Add a 'dropped events' counterSteven Rostedt (11):
tracing: Allow tracers to start at core initcall
tracing: Expand ring buffer whentrace_printk()is used
tracing: Enable comm recording iftrace_printk()is used
tracing: Havetracing_sched_wakeup_trace()use standardunlock_commit
tracing: Cache comms only after an event occurred
tracing: Separate open function fromset_eventandavailable_events
tracing: Remove unused functionunregister_tracer()
tracing: Maketracing_enabledbe equal totracing_on
tracing: Remove deprecatedtracing_enabledfile
tracing: Useirq_workfor wake ups and remove *_nowake_*() functions
tracing: Addtrace_optionskernel command line parameterVaibhav Nagarnaik (1):
tracing: Cleanup unnecessary function declarationsYoshihiro YUNOMAE (2):
ring-buffer: Change unsigned long type ofring_buffer_oldest_event_ts()to u64
tracing: Show raw time stamp on stats per cpu using counter or tsc mode fortrace_clock----
Documentation/kernel-parameters.txt | 16 ++ arch/alpha/include/asm/Kbuild | 1 + arch/arm/include/asm/Kbuild | 1 + arch/arm64/include/asm/Kbuild | 1 + arch/avr32/include/asm/Kbuild | 1 + arch/blackfin/include/asm/Kbuild | 1 + arch/c6x/include/asm/Kbuild | 1 + arch/cris/include/asm/Kbuild | 1 + arch/frv/include/asm/Kbuild | 1 + arch/h8300/include/asm/Kbuild | 1 + arch/hexagon/include/asm/Kbuild | 1 + arch/ia64/include/asm/Kbuild | 1 + arch/m32r/include/asm/Kbuild | 1 + arch/m68k/include/asm/Kbuild | 1 + arch/microblaze/include/asm/Kbuild | 1 + arch/mips/include/asm/Kbuild | 1 + arch/mn10300/include/asm/Kbuild | 1 + arch/openrisc/include/asm/Kbuild | 1 + arch/parisc/include/asm/Kbuild | 2 +- arch/powerpc/include/asm/Kbuild | 1 + arch/s390/include/asm/Kbuild | 1 + arch/score/include/asm/Kbuild | 1 + arch/sh/include/asm/Kbuild | 1 + arch/sparc/include/asm/Kbuild | 1 + arch/tile/include/asm/Kbuild | 1 + arch/um/include/asm/Kbuild | 1 + arch/unicore32/include/asm/Kbuild | 1 + arch/x86/include/asm/trace_clock.h | 16 ++ arch/x86/kernel/Makefile | 1 + arch/x86/kernel/trace_clock.c | 21 ++ arch/xtensa/include/asm/Kbuild | 1 + include/asm-generic/trace_clock.h | 16 ++ include/linux/ftrace_event.h | 20 +- include/linux/kernel.h | 7 +- include/linux/ring_buffer.h | 3 +- include/linux/trace_clock.h | 2 + include/trace/ftrace.h | 3 +- include/trace/syscall.h | 23 -- kernel/trace/Kconfig | 1 + kernel/trace/ftrace.c | 6 +- kernel/trace/ring_buffer.c | 51 ++++- kernel/trace/trace.c | 411 ++++++++++++++++++---------------- kernel/trace/trace.h | 18 +- kernel/trace/trace_branch.c | 4 +- kernel/trace/trace_events.c | 51 +++-- kernel/trace/trace_events_filter.c | 4 +- kernel/trace/trace_functions.c | 5 +- kernel/trace/trace_functions_graph.c | 6 +- kernel/trace/trace_irqsoff.c | 14 +- kernel/trace/trace_kprobe.c | 10 +- kernel/trace/trace_output.c | 80 ++++--- kernel/trace/trace_probe.c | 14 +- kernel/trace/trace_sched_switch.c | 4 +- kernel/trace/trace_sched_wakeup.c | 10 +- kernel/trace/trace_selftest.c | 13 +- kernel/trace/trace_syscalls.c | 61 +++-- kernel/trace/trace_uprobe.c | 2 +- 57 files changed, 539 insertions(+), 382 deletions(-)