diff options
| author | Tom Zanussi <tom.zanussi@linux.intel.com> | 2013-10-24 09:34:17 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2013-11-05 16:50:20 -0500 |
| commit | f306cc82a93d6b19f01634b80c580b9755c8b7cc (patch) | |
| tree | 1a9ef8d44ed192185e4d6da5f7154f9a1c2075cb /kernel/trace | |
| parent | f02b625d0341519238ab3d9cc8706ff4bd45fb89 (diff) | |
tracing: Update event filters for multibuffer
The trace event filters are still tied to event calls rather than
event files, which means you don't get what you'd expect when using
filters in the multibuffer case:
Before:
# echo 'bytes_alloc > 8192' > /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
# cat /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
bytes_alloc > 8192
# mkdir /sys/kernel/debug/tracing/instances/test1
# echo 'bytes_alloc > 2048' > /sys/kernel/debug/tracing/instances/test1/events/kmem/kmalloc/filter
# cat /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
bytes_alloc > 2048
# cat /sys/kernel/debug/tracing/instances/test1/events/kmem/kmalloc/filter
bytes_alloc > 2048
Setting the filter in tracing/instances/test1/events shouldn't affect
the same event in tracing/events as it does above.
After:
# echo 'bytes_alloc > 8192' > /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
# cat /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
bytes_alloc > 8192
# mkdir /sys/kernel/debug/tracing/instances/test1
# echo 'bytes_alloc > 2048' > /sys/kernel/debug/tracing/instances/test1/events/kmem/kmalloc/filter
# cat /sys/kernel/debug/tracing/events/kmem/kmalloc/filter
bytes_alloc > 8192
# cat /sys/kernel/debug/tracing/instances/test1/events/kmem/kmalloc/filter
bytes_alloc > 2048
We'd like to just move the filter directly from ftrace_event_call to
ftrace_event_file, but there are a couple cases that don't yet have
multibuffer support and therefore have to continue using the current
event_call-based filters. For those cases, a new USE_CALL_FILTER bit
is added to the event_call flags, whose main purpose is to keep the
old behavior for those cases until they can be updated with
multibuffer support; at that point, the USE_CALL_FILTER flag (and the
new associated call_filter_check_discard() function) can go away.
The multibuffer support also made filter_current_check_discard()
redundant, so this change removes that function as well and replaces
it with filter_check_discard() (or call_filter_check_discard() as
appropriate).
Link: http://lkml.kernel.org/r/f16e9ce4270c62f46b2e966119225e1c3cca7e60.1382620672.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/trace.c | 40 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 18 | ||||
| -rw-r--r-- | kernel/trace/trace_branch.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 23 | ||||
| -rw-r--r-- | kernel/trace/trace_events_filter.c | 218 | ||||
| -rw-r--r-- | kernel/trace/trace_export.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_functions_graph.c | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_kprobe.c | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_mmiotrace.c | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_sched_switch.c | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_syscalls.c | 8 | ||||
| -rw-r--r-- | kernel/trace/trace_uprobe.c | 3 |
12 files changed, 239 insertions, 91 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 063a92bad578..489da8b19f30 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -235,13 +235,33 @@ void trace_array_put(struct trace_array *this_tr) | |||
| 235 | mutex_unlock(&trace_types_lock); | 235 | mutex_unlock(&trace_types_lock); |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | int filter_current_check_discard(struct ring_buffer *buffer, | 238 | int filter_check_discard(struct ftrace_event_file *file, void *rec, |
| 239 | struct ftrace_event_call *call, void *rec, | 239 | struct ring_buffer *buffer, |
| 240 | struct ring_buffer_event *event) | 240 | struct ring_buffer_event *event) |
| 241 | { | 241 | { |
| 242 | return filter_check_discard(call, rec, buffer, event); | 242 | if (unlikely(file->flags & FTRACE_EVENT_FL_FILTERED) && |
| 243 | !filter_match_preds(file->filter, rec)) { | ||
| 244 | ring_buffer_discard_commit(buffer, event); | ||
| 245 | return 1; | ||
| 246 | } | ||
| 247 | |||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | EXPORT_SYMBOL_GPL(filter_check_discard); | ||
| 251 | |||
| 252 | int call_filter_check_discard(struct ftrace_event_call *call, void *rec, | ||
| 253 | struct ring_buffer *buffer, | ||
| 254 | struct ring_buffer_event *event) | ||
| 255 | { | ||
| 256 | if (unlikely(call->flags & TRACE_EVENT_FL_FILTERED) && | ||
| 257 | !filter_match_preds(call->filter, rec)) { | ||
| 258 | ring_buffer_discard_commit(buffer, event); | ||
| 259 | return 1; | ||
| 260 | } | ||
| 261 | |||
| 262 | return 0; | ||
| 243 | } | 263 | } |
| 244 | EXPORT_SYMBOL_GPL(filter_current_check_discard); | 264 | EXPORT_SYMBOL_GPL(call_filter_check_discard); |
| 245 | 265 | ||
| 246 | cycle_t buffer_ftrace_now(struct trace_buffer *buf, int cpu) | 266 | cycle_t buffer_ftrace_now(struct trace_buffer *buf, int cpu) |
| 247 | { | 267 | { |
| @@ -1633,7 +1653,7 @@ trace_function(struct trace_array *tr, | |||
| 1633 | entry->ip = ip; | 1653 | entry->ip = ip; |
| 1634 | entry->parent_ip = parent_ip; | 1654 | entry->parent_ip = parent_ip; |
| 1635 | 1655 | ||
| 1636 | if (!filter_check_discard(call, entry, buffer, event)) | 1656 | if (!call_filter_check_discard(call, entry, buffer, event)) |
| 1637 | __buffer_unlock_commit(buffer, event); | 1657 | __buffer_unlock_commit(buffer, event); |
| 1638 | } | 1658 | } |
| 1639 | 1659 | ||
| @@ -1717,7 +1737,7 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer, | |||
| 1717 | 1737 | ||
| 1718 | entry->size = trace.nr_entries; | 1738 | entry->size = trace.nr_entries; |
| 1719 | 1739 | ||
| 1720 | if (!filter_check_discard(call, entry, buffer, event)) | 1740 | if (!call_filter_check_discard(call, entry, buffer, event)) |
| 1721 | __buffer_unlock_commit(buffer, event); | 1741 | __buffer_unlock_commit(buffer, event); |
| 1722 | 1742 | ||
| 1723 | out: | 1743 | out: |
| @@ -1819,7 +1839,7 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc) | |||
| 1819 | trace.entries = entry->caller; | 1839 | trace.entries = entry->caller; |
| 1820 | 1840 | ||
| 1821 | save_stack_trace_user(&trace); | 1841 | save_stack_trace_user(&trace); |
| 1822 | if (!filter_check_discard(call, entry, buffer, event)) | 1842 | if (!call_filter_check_discard(call, entry, buffer, event)) |
| 1823 | __buffer_unlock_commit(buffer, event); | 1843 | __buffer_unlock_commit(buffer, event); |
| 1824 | 1844 | ||
| 1825 | out_drop_count: | 1845 | out_drop_count: |
| @@ -2011,7 +2031,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) | |||
| 2011 | entry->fmt = fmt; | 2031 | entry->fmt = fmt; |
| 2012 | 2032 | ||
| 2013 | memcpy(entry->buf, tbuffer, sizeof(u32) * len); | 2033 | memcpy(entry->buf, tbuffer, sizeof(u32) * len); |
| 2014 | if (!filter_check_discard(call, entry, buffer, event)) { | 2034 | if (!call_filter_check_discard(call, entry, buffer, event)) { |
| 2015 | __buffer_unlock_commit(buffer, event); | 2035 | __buffer_unlock_commit(buffer, event); |
| 2016 | ftrace_trace_stack(buffer, flags, 6, pc); | 2036 | ftrace_trace_stack(buffer, flags, 6, pc); |
| 2017 | } | 2037 | } |
| @@ -2066,7 +2086,7 @@ __trace_array_vprintk(struct ring_buffer *buffer, | |||
| 2066 | 2086 | ||
| 2067 | memcpy(&entry->buf, tbuffer, len); | 2087 | memcpy(&entry->buf, tbuffer, len); |
| 2068 | entry->buf[len] = '\0'; | 2088 | entry->buf[len] = '\0'; |
| 2069 | if (!filter_check_discard(call, entry, buffer, event)) { | 2089 | if (!call_filter_check_discard(call, entry, buffer, event)) { |
| 2070 | __buffer_unlock_commit(buffer, event); | 2090 | __buffer_unlock_commit(buffer, event); |
| 2071 | ftrace_trace_stack(buffer, flags, 6, pc); | 2091 | ftrace_trace_stack(buffer, flags, 6, pc); |
| 2072 | } | 2092 | } |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index d1cf5159bec0..12d1a612a73e 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -1007,9 +1007,9 @@ struct filter_pred { | |||
| 1007 | 1007 | ||
| 1008 | extern enum regex_type | 1008 | extern enum regex_type |
| 1009 | filter_parse_regex(char *buff, int len, char **search, int *not); | 1009 | filter_parse_regex(char *buff, int len, char **search, int *not); |
| 1010 | extern void print_event_filter(struct ftrace_event_call *call, | 1010 | extern void print_event_filter(struct ftrace_event_file *file, |
| 1011 | struct trace_seq *s); | 1011 | struct trace_seq *s); |
| 1012 | extern int apply_event_filter(struct ftrace_event_call *call, | 1012 | extern int apply_event_filter(struct ftrace_event_file *file, |
| 1013 | char *filter_string); | 1013 | char *filter_string); |
| 1014 | extern int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir, | 1014 | extern int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir, |
| 1015 | char *filter_string); | 1015 | char *filter_string); |
| @@ -1020,20 +1020,6 @@ extern int filter_assign_type(const char *type); | |||
| 1020 | struct ftrace_event_field * | 1020 | struct ftrace_event_field * |
| 1021 | trace_find_event_field(struct ftrace_event_call *call, char *name); | 1021 | trace_find_event_field(struct ftrace_event_call *call, char *name); |
| 1022 | 1022 | ||
| 1023 | static inline int | ||
| 1024 | filter_check_discard(struct ftrace_event_call *call, void *rec, | ||
| 1025 | struct ring_buffer *buffer, | ||
| 1026 | struct ring_buffer_event *event) | ||
| 1027 | { | ||
| 1028 | if (unlikely(call->flags & TRACE_EVENT_FL_FILTERED) && | ||
| 1029 | !filter_match_preds(call->filter, rec)) { | ||
| 1030 | ring_buffer_discard_commit(buffer, event); | ||
| 1031 | return 1; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | return 0; | ||
| 1035 | } | ||
| 1036 | |||
| 1037 | extern void trace_event_enable_cmd_record(bool enable); | 1023 | extern void trace_event_enable_cmd_record(bool enable); |
| 1038 | extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr); | 1024 | extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr); |
| 1039 | extern int event_trace_del_tracer(struct trace_array *tr); | 1025 | extern int event_trace_del_tracer(struct trace_array *tr); |
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index d594da0dc03c..697fb9bac8f0 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c | |||
| @@ -78,7 +78,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect) | |||
| 78 | entry->line = f->line; | 78 | entry->line = f->line; |
| 79 | entry->correct = val == expect; | 79 | entry->correct = val == expect; |
| 80 | 80 | ||
| 81 | if (!filter_check_discard(call, entry, buffer, event)) | 81 | if (!call_filter_check_discard(call, entry, buffer, event)) |
| 82 | __buffer_unlock_commit(buffer, event); | 82 | __buffer_unlock_commit(buffer, event); |
| 83 | 83 | ||
| 84 | out: | 84 | out: |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 368a4d50cc30..043f833246a0 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -989,7 +989,7 @@ static ssize_t | |||
| 989 | event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, | 989 | event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, |
| 990 | loff_t *ppos) | 990 | loff_t *ppos) |
| 991 | { | 991 | { |
| 992 | struct ftrace_event_call *call; | 992 | struct ftrace_event_file *file; |
| 993 | struct trace_seq *s; | 993 | struct trace_seq *s; |
| 994 | int r = -ENODEV; | 994 | int r = -ENODEV; |
| 995 | 995 | ||
| @@ -1004,12 +1004,12 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
| 1004 | trace_seq_init(s); | 1004 | trace_seq_init(s); |
| 1005 | 1005 | ||
| 1006 | mutex_lock(&event_mutex); | 1006 | mutex_lock(&event_mutex); |
| 1007 | call = event_file_data(filp); | 1007 | file = event_file_data(filp); |
| 1008 | if (call) | 1008 | if (file) |
| 1009 | print_event_filter(call, s); | 1009 | print_event_filter(file, s); |
