aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-04 19:57:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-04 19:57:04 -0500
commit78baab7aa843ef01644195d341bee118cbe4bf19 (patch)
tree73502edec6885609de4bd359cc0fc1b33af7a333
parente3c2ef41f88e50c8557270868600d3132028af3b (diff)
parente57cbaf0eb006eaa207395f3bfd7ce52c1b5539c (diff)
Merge tag 'trace-fixes-v4.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing fix from Steven Rostedt: "A feature was added in 4.3 that allowed users to filter trace points on a tasks "comm" field. But this prevented filtering on a comm field that is within a trace event (like sched_migrate_task). When trying to filter on when a program migrated, this change prevented the filtering of the sched_migrate_task. To fix this, the event fields are examined first, and then the extra fields like "comm" and "cpu" are examined. Also, instead of testing to assign the comm filter function based on the field's name, the generic comm field is given a new filter type (FILTER_COMM). When this field is used to filter the type is checked. The same is done for the cpu filter field. Two new special filter types are added: "COMM" and "CPU". This allows users to still filter the tasks comm for events that have "comm" as one of their fields, in cases that users would like to filter sched_migrate_task on the comm of the task that called the event, and not the comm of the task that is being migrated" * tag 'trace-fixes-v4.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Do not have 'comm' filter override event 'comm' field
-rw-r--r--include/linux/trace_events.h2
-rw-r--r--kernel/trace/trace_events.c14
-rw-r--r--kernel/trace/trace_events_filter.c13
3 files changed, 17 insertions, 12 deletions
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 429fdfc3baf5..925730bc9fc1 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -568,6 +568,8 @@ enum {
568 FILTER_DYN_STRING, 568 FILTER_DYN_STRING,
569 FILTER_PTR_STRING, 569 FILTER_PTR_STRING,
570 FILTER_TRACE_FN, 570 FILTER_TRACE_FN,
571 FILTER_COMM,
572 FILTER_CPU,
571}; 573};
572 574
573extern int trace_event_raw_init(struct trace_event_call *call); 575extern int trace_event_raw_init(struct trace_event_call *call);
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index ab09829d3b97..05ddc0820771 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -97,16 +97,16 @@ trace_find_event_field(struct trace_event_call *call, char *name)
97 struct ftrace_event_field *field; 97 struct ftrace_event_field *field;
98 struct list_head *head; 98 struct list_head *head;
99 99
100 field = __find_event_field(&ftrace_generic_fields, name); 100 head = trace_get_fields(call);
101 field = __find_event_field(head, name);
101 if (field) 102 if (field)
102 return field; 103 return field;
103 104
104 field = __find_event_field(&ftrace_common_fields, name); 105 field = __find_event_field(&ftrace_generic_fields, name);
105 if (field) 106 if (field)
106 return field; 107 return field;
107 108
108 head = trace_get_fields(call); 109 return __find_event_field(&ftrace_common_fields, name);
109 return __find_event_field(head, name);
110} 110}
111 111
112static int __trace_define_field(struct list_head *head, const char *type, 112static int __trace_define_field(struct list_head *head, const char *type,
@@ -171,8 +171,10 @@ static int trace_define_generic_fields(void)
171{ 171{
172 int ret; 172 int ret;
173 173
174 __generic_field(int, cpu, FILTER_OTHER); 174 __generic_field(int, CPU, FILTER_CPU);
175 __generic_field(char *, comm, FILTER_PTR_STRING); 175 __generic_field(int, cpu, FILTER_CPU);
176 __generic_field(char *, COMM, FILTER_COMM);
177 __generic_field(char *, comm, FILTER_COMM);
176 178
177 return ret; 179 return ret;
178} 180}
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index f93a219b18da..6816302542b2 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -1043,13 +1043,14 @@ static int init_pred(struct filter_parse_state *ps,
1043 return -EINVAL; 1043 return -EINVAL;
1044 } 1044 }
1045 1045
1046 if (is_string_field(field)) { 1046 if (field->filter_type == FILTER_COMM) {
1047 filter_build_regex(pred);
1048 fn = filter_pred_comm;
1049 pred->regex.field_len = TASK_COMM_LEN;
1050 } else if (is_string_field(field)) {
1047 filter_build_regex(pred); 1051 filter_build_regex(pred);
1048 1052
1049 if (!strcmp(field->name, "comm")) { 1053 if (field->filter_type == FILTER_STATIC_STRING) {
1050 fn = filter_pred_comm;
1051 pred->regex.field_len = TASK_COMM_LEN;
1052 } else if (field->filter_type == FILTER_STATIC_STRING) {
1053 fn = filter_pred_string; 1054 fn = filter_pred_string;
1054 pred->regex.field_len = field->size; 1055 pred->regex.field_len = field->size;
1055 } else if (field->filter_type == FILTER_DYN_STRING) 1056 } else if (field->filter_type == FILTER_DYN_STRING)
@@ -1072,7 +1073,7 @@ static int init_pred(struct filter_parse_state *ps,
1072 } 1073 }
1073 pred->val = val; 1074 pred->val = val;
1074 1075
1075 if (!strcmp(field->name, "cpu")) 1076 if (field->filter_type == FILTER_CPU)
1076 fn = filter_pred_cpu; 1077 fn = filter_pred_cpu;
1077 else 1078 else
1078 fn = select_comparison_fn(pred->op, field->size, 1079 fn = select_comparison_fn(pred->op, field->size,