From: Linus Torvalds Date: Fri, 6 Nov 2015 21:30:20 +0000 (-0800) Subject: Merge tag 'trace-v4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux... X-Git-Tag: v4.4-rc1~85 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=22402cd0af685c1a5d067c87db3051db7fff7709;hp=7c623cac4939fb36916c029609dd22e3dec0a014;p=linux-2.6-block.git Merge tag 'trace-v4.4' of git://git./linux/kernel/git/rostedt/linux-trace Pull tracking updates from Steven Rostedt: "Most of the changes are clean ups and small fixes. Some of them have stable tags to them. I searched through my INBOX just as the merge window opened and found lots of patches to pull. I ran them through all my tests and they were in linux-next for a few days. Features added this release: ---------------------------- - Module globbing. You can now filter function tracing to several modules. # echo '*:mod:*snd*' > set_ftrace_filter (Dmitry Safonov) - Tracer specific options are now visible even when the tracer is not active. It was rather annoying that you can only see and modify tracer options after enabling the tracer. Now they are in the options/ directory even when the tracer is not active. Although they are still only visible when the tracer is active in the trace_options file. - Trace options are now per instance (although some of the tracer specific options are global) - New tracefs file: set_event_pid. If any pid is added to this file, then all events in the instance will filter out events that are not part of this pid. sched_switch and sched_wakeup events handle next and the wakee pids" * tag 'trace-v4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (68 commits) tracefs: Fix refcount imbalance in start_creating() tracing: Put back comma for empty fields in boot string parsing tracing: Apply tracer specific options from kernel command line. tracing: Add some documentation about set_event_pid ring_buffer: Remove unneeded smp_wmb() before wakeup of reader benchmark tracing: Allow dumping traces without tracking trace started cpus ring_buffer: Fix more races when terminating the producer in the benchmark ring_buffer: Do no not complete benchmark reader too early tracing: Remove redundant TP_ARGS redefining tracing: Rename max_stack_lock to stack_trace_max_lock tracing: Allow arch-specific stack tracer recordmcount: arm64: Replace the ignored mcount call into nop recordmcount: Fix endianness handling bug for nop_mcount tracepoints: Fix documentation of RCU lockdep checks tracing: ftrace_event_is_function() can return boolean tracing: is_legal_op() can return boolean ring-buffer: rb_event_is_commit() can return boolean ring-buffer: rb_per_cpu_empty() can return boolean ring_buffer: ring_buffer_empty{cpu}() can return boolean ring-buffer: rb_is_reader_page() can return boolean ... --- diff --git a/Documentation/trace/events.txt b/Documentation/trace/events.txt index 75d25a1d6e42..c010be8c85d7 100644 --- a/Documentation/trace/events.txt +++ b/Documentation/trace/events.txt @@ -288,6 +288,24 @@ prev_pid == 0 # cat sched_wakeup/filter common_pid == 0 +5.4 PID filtering +----------------- + +The set_event_pid file in the same directory as the top events directory +exists, will filter all events from tracing any task that does not have the +PID listed in the set_event_pid file. + +# cd /sys/kernel/debug/tracing +# echo $$ > set_event_pid +# echo 1 > events/enabled + +Will only trace events for the current task. + +To add more PIDs without losing the PIDs already included, use '>>'. + +# echo 123 244 1 >> set_event_pid + + 6. Event triggers ================= diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt index ef621d34ba5b..f52f297cb406 100644 --- a/Documentation/trace/ftrace.txt +++ b/Documentation/trace/ftrace.txt @@ -204,6 +204,12 @@ of ftrace. Here is a list of some of the key files: Have the function tracer only trace a single thread. + set_event_pid: + + Have the events only trace a task with a PID listed in this file. + Note, sched_switch and sched_wake_up will also trace events + listed in this file. + set_graph_function: Set a "trigger" function where tracing should start @@ -2437,6 +2443,23 @@ The following commands are supported: echo '!writeback*:mod:ext3' >> set_ftrace_filter + Mod command supports module globbing. Disable tracing for all + functions except a specific module: + + echo '!*:mod:!ext3' >> set_ftrace_filter + + Disable tracing for all modules, but still trace kernel: + + echo '!*:mod:*' >> set_ftrace_filter + + Enable filter only for kernel: + + echo '*write*:mod:!*' >> set_ftrace_filter + + Enable filter for module globbing: + + echo '*write*:mod:*snd*' >> set_ftrace_filter + - traceon/traceoff These commands turn tracing on and off when the specified functions are hit. The parameter determines how many times the diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 8b7b0a51e742..311bcf338f07 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -556,6 +556,7 @@ void ftrace_replace_code(int enable) run_sync(); report = "updating code"; + count = 0; for_ftrace_rec_iter(iter) { rec = ftrace_rec_iter_record(iter); @@ -563,11 +564,13 @@ void ftrace_replace_code(int enable) ret = add_update(rec, enable); if (ret) goto remove_breakpoints; + count++; } run_sync(); report = "removing breakpoints"; + count = 0; for_ftrace_rec_iter(iter) { rec = ftrace_rec_iter_record(iter); @@ -575,6 +578,7 @@ void ftrace_replace_code(int enable) ret = finish_update(rec, enable); if (ret) goto remove_breakpoints; + count++; } run_sync(); diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index cbc8d5d2755a..c66f2423e1f5 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -340,8 +340,12 @@ static struct dentry *start_creating(const char *name, struct dentry *parent) dput(dentry); dentry = ERR_PTR(-EEXIST); } - if (IS_ERR(dentry)) + + if (IS_ERR(dentry)) { mutex_unlock(&parent->d_inode->i_mutex); + simple_release_fs(&tracefs_mount, &tracefs_mount_count); + } + return dentry; } diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 6cd8c0ee4b6f..eae6548efbf0 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -263,7 +263,18 @@ static inline void ftrace_kill(void) { } #endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_STACK_TRACER + +#define STACK_TRACE_ENTRIES 500 + +struct stack_trace; + +extern unsigned stack_trace_index[]; +extern struct stack_trace stack_trace_max; +extern unsigned long stack_trace_max_size; +extern arch_spinlock_t stack_trace_max_lock; + extern int stack_tracer_enabled; +void stack_trace_print(void); int stack_trace_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index e2c13cd863bd..4acc552e9279 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -154,8 +154,8 @@ ring_buffer_swap_cpu(struct ring_buffer *buffer_a, } #endif -int ring_buffer_empty(struct ring_buffer *buffer); -int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu); +bool ring_buffer_empty(struct ring_buffer *buffer); +bool ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu); void ring_buffer_record_disable(struct ring_buffer *buffer); void ring_buffer_record_enable(struct ring_buffer *buffer); diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index ed27917cabc9..429fdfc3baf5 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -168,13 +168,12 @@ struct ring_buffer_event * trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer, int type, unsigned long len, unsigned long flags, int pc); -void trace_current_buffer_unlock_commit(struct ring_buffer *buffer, - struct ring_buffer_event *event, - unsigned long flags, int pc); -void trace_buffer_unlock_commit(struct ring_buffer *buffer, +void trace_buffer_unlock_commit(struct trace_array *tr, + struct ring_buffer *buffer, struct ring_buffer_event *event, unsigned long flags, int pc); -void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer, +void trace_buffer_unlock_commit_regs(struct trace_array *tr, + struct ring_buffer *buffer, struct ring_buffer_event *event, unsigned long flags, int pc, struct pt_regs *regs); @@ -329,6 +328,7 @@ enum { EVENT_FILE_FL_SOFT_DISABLED_BIT, EVENT_FILE_FL_TRIGGER_MODE_BIT, EVENT_FILE_FL_TRIGGER_COND_BIT, + EVENT_FILE_FL_PID_FILTER_BIT, }; /* @@ -342,6 +342,7 @@ enum { * tracepoint may be enabled) * TRIGGER_MODE - When set, invoke the triggers associated with the event * TRIGGER_COND - When set, one or more triggers has an associated filter + * PID_FILTER - When set, the event is filtered based on pid */ enum { EVENT_FILE_FL_ENABLED = (1 << EVENT_FILE_FL_ENABLED_BIT), @@ -352,6 +353,7 @@ enum { EVENT_FILE_FL_SOFT_DISABLED = (1 << EVENT_FILE_FL_SOFT_DISABLED_BIT), EVENT_FILE_FL_TRIGGER_MODE = (1 << EVENT_FILE_FL_TRIGGER_MODE_BIT), EVENT_FILE_FL_TRIGGER_COND = (1 << EVENT_FILE_FL_TRIGGER_COND_BIT), + EVENT_FILE_FL_PID_FILTER = (1 << EVENT_FILE_FL_PID_FILTER_BIT), }; struct trace_event_file { @@ -430,6 +432,8 @@ extern enum event_trigger_type event_triggers_call(struct trace_event_file *file extern void event_triggers_post_call(struct trace_event_file *file, enum event_trigger_type tt); +bool trace_event_ignore_this_pid(struct trace_event_file *trace_file); + /** * trace_trigger_soft_disabled - do triggers and test if soft disabled * @file: The file pointer of the event to test @@ -449,6 +453,8 @@ trace_trigger_soft_disabled(struct trace_event_file *file) event_triggers_call(file, NULL); if (eflags & EVENT_FILE_FL_SOFT_DISABLED) return true; + if (eflags & EVENT_FILE_FL_PID_FILTER) + return trace_event_ignore_this_pid(file); } return false; } @@ -508,7 +514,7 @@ event_trigger_unlock_commit(struct trace_event_file *file, enum event_trigger_type tt = ETT_NONE; if (!__event_trigger_test_discard(file, buffer, event, entry, &tt)) - trace_buffer_unlock_commit(buffer, event, irq_flags, pc); + trace_buffer_unlock_commit(file->tr, buffer, event, irq_flags, pc); if (tt) event_triggers_post_call(file, tt); @@ -540,7 +546,7 @@ event_trigger_unlock_commit_regs(struct trace_event_file *file, enum event_trigger_type tt = ETT_NONE; if (!__event_trigger_test_discard(file, buffer, event, entry, &tt)) - trace_buffer_unlock_commit_regs(buffer, event, + trace_buffer_unlock_commit_regs(file->tr, buffer, event, irq_flags, pc, regs); if (tt) diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index a5f7f3ecafa3..696a339c592c 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -26,6 +26,7 @@ struct notifier_block; struct tracepoint_func { void *func; void *data; + int prio; }; struct tracepoint { @@ -42,9 +43,14 @@ struct trace_enum_map { unsigned long enum_value; }; +#define TRACEPOINT_DEFAULT_PRIO 10 + extern int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data); extern int +tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data, + int prio); +extern int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data); extern void for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv), @@ -111,7 +117,18 @@ extern void syscall_unregfunc(void); #define TP_ARGS(args...) args #define TP_CONDITION(args...) args -#ifdef CONFIG_TRACEPOINTS +/* + * Individual subsystem my have a separate configuration to + * enable their tracepoints. By default, this file will create + * the tracepoints if CONFIG_TRACEPOINT is defined. If a subsystem + * wants to be able to disable its tracepoints from being created + * it can define NOTRACE before including the tracepoint headers. + */ +#if defined(CONFIG_TRACEPOINTS) && !defined(NOTRACE) +#define TRACEPOINTS_ENABLED +#endif + +#ifdef TRACEPOINTS_ENABLED /* * it_func[0] is never NULL because there is at least one element in the array @@ -167,10 +184,11 @@ extern void syscall_unregfunc(void); * structure. Force alignment to the same alignment as the section start. * * When lockdep is enabled, we make sure to always do the RCU portions of - * the tracepoint code, regardless of whether tracing is on or we match the - * condition. This lets us find RCU issues triggered with tracepoints even - * when this tracepoint is off. This code has no purpose other than poking - * RCU a bit. + * the tracepoint code, regardless of whether tracing is on. However, + * don't check if the condition is false, due to interaction with idle + * instrumentation. This lets us find RCU issues triggered with tracepoints + * even when this tracepoint is off. This code has no purpose other than + * poking RCU a bit. */ #define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \ extern struct tracepoint __tracepoint_##name; \ @@ -196,6 +214,13 @@ extern void syscall_unregfunc(void); (void *)probe, data); \ } \ static inline int \ + register_trace_prio_##name(void (*probe)(data_proto), void *data,\ + int prio) \ + { \ + return tracepoint_probe_register_prio(&__tracepoint_##name, \ + (void *)probe, data, prio); \ + } \ + static inline int \ unregister_trace_##name(void (*probe)(data_proto), void *data) \ { \ return tracepoint_probe_unregister(&__tracepoint_##name,\ @@ -234,7 +259,7 @@ extern void syscall_unregfunc(void); #define EXPORT_TRACEPOINT_SYMBOL(name) \ EXPORT_SYMBOL(__tracepoint_##name) -#else /* !CONFIG_TRACEPOINTS */ +#else /* !TRACEPOINTS_ENABLED */ #define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \ static inline void trace_##name(proto) \ { } \ @@ -266,7 +291,7 @@ extern void syscall_unregfunc(void); #define EXPORT_TRACEPOINT_SYMBOL_GPL(name) #define EXPORT_TRACEPOINT_SYMBOL(name) -#endif /* CONFIG_TRACEPOINTS */ +#endif /* TRACEPOINTS_ENABLED */ #ifdef CONFIG_TRACING /** diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h index 09b3880105a9..2d8639ea64d5 100644 --- a/include/trace/define_trace.h +++ b/include/trace/define_trace.h @@ -86,7 +86,7 @@ #undef DECLARE_TRACE #define DECLARE_TRACE(name, proto, args) -#ifdef CONFIG_EVENT_TRACING +#ifdef TRACEPOINTS_ENABLED #include #include #endif diff --git a/include/trace/events/gpio.h b/include/trace/events/gpio.h index 927a8ad9e51b..2da73b92d47e 100644 --- a/include/trace/events/gpio.h +++ b/include/trace/events/gpio.h @@ -1,6 +1,10 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM gpio +#ifndef CONFIG_TRACING_EVENTS_GPIO +#define NOTRACE +#endif + #if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_GPIO_H diff --git a/include/trace/perf.h b/include/trace/perf.h index 1b5443cebedc..26486fcd74ce 100644 --- a/include/trace/perf.h +++ b/include/trace/perf.h @@ -1,261 +1,3 @@ -/* - * Stage 4 of the trace events. - * - * Override the macros in to include the following: - * - * For those macros defined with TRACE_EVENT: - * - * static struct trace_event_call event_; - * - * static void trace_event_raw_event_(void *__data, proto) - * { - * struct trace_event_file *trace_file = __data; - * struct trace_event_call *event_call = trace_file->event_call; - * struct trace_event_data_offsets_ __maybe_unused __data_offsets; - * unsigned long eflags = trace_file->flags; - * enum event_trigger_type __tt = ETT_NONE; - * struct ring_buffer_event *event; - * struct trace_event_raw_ *entry; <-- defined in stage 1 - * struct ring_buffer *buffer; - * unsigned long irq_flags; - * int __data_size; - * int pc; - * - * if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) { - * if (eflags & EVENT_FILE_FL_TRIGGER_MODE) - * event_triggers_call(trace_file, NULL); - * if (eflags & EVENT_FILE_FL_SOFT_DISABLED) - * return; - * } - * - * local_save_flags(irq_flags); - * pc = preempt_count(); - * - * __data_size = trace_event_get_offsets_(&__data_offsets, args); - * - * event = trace_event_buffer_lock_reserve(&buffer, trace_file, - * event_->event.type, - * sizeof(*entry) + __data_size, - * irq_flags, pc); - * if (!event) - * return; - * entry = ring_buffer_event_data(event); - * - * { ; } <-- Here we assign the entries by the __field and - * __array macros. - * - * if (eflags & EVENT_FILE_FL_TRIGGER_COND) - * __tt = event_triggers_call(trace_file, entry); - * - * if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, - * &trace_file->flags)) - * ring_buffer_discard_commit(buffer, event); - * else if (!filter_check_discard(trace_file, entry, buffer, event)) - * trace_buffer_unlock_commit(buffer, event, irq_flags, pc); - * - * if (__tt) - * event_triggers_post_call(trace_file, __tt); - * } - * - * static struct trace_event ftrace_event_type_ = { - * .trace = trace_raw_output_, <-- stage 2 - * }; - * - * static char print_fmt_[] = ; - * - * static struct trace_event_class __used event_class_