Commit 78baab7a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'trace-fixes-v4.5-rc6' of...

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
parents e3c2ef41 e57cbaf0
...@@ -568,6 +568,8 @@ enum { ...@@ -568,6 +568,8 @@ enum {
FILTER_DYN_STRING, FILTER_DYN_STRING,
FILTER_PTR_STRING, FILTER_PTR_STRING,
FILTER_TRACE_FN, FILTER_TRACE_FN,
FILTER_COMM,
FILTER_CPU,
}; };
extern int trace_event_raw_init(struct trace_event_call *call); extern int trace_event_raw_init(struct trace_event_call *call);
......
...@@ -97,16 +97,16 @@ trace_find_event_field(struct trace_event_call *call, char *name) ...@@ -97,16 +97,16 @@ trace_find_event_field(struct trace_event_call *call, char *name)
struct ftrace_event_field *field; struct ftrace_event_field *field;
struct list_head *head; struct list_head *head;
field = __find_event_field(&ftrace_generic_fields, name); head = trace_get_fields(call);
field = __find_event_field(head, name);
if (field) if (field)
return field; return field;
field = __find_event_field(&ftrace_common_fields, name); field = __find_event_field(&ftrace_generic_fields, name);
if (field) if (field)
return field; return field;
head = trace_get_fields(call); return __find_event_field(&ftrace_common_fields, name);
return __find_event_field(head, name);
} }
static int __trace_define_field(struct list_head *head, const char *type, static int __trace_define_field(struct list_head *head, const char *type,
...@@ -171,8 +171,10 @@ static int trace_define_generic_fields(void) ...@@ -171,8 +171,10 @@ static int trace_define_generic_fields(void)
{ {
int ret; int ret;
__generic_field(int, cpu, FILTER_OTHER); __generic_field(int, CPU, FILTER_CPU);
__generic_field(char *, comm, FILTER_PTR_STRING); __generic_field(int, cpu, FILTER_CPU);
__generic_field(char *, COMM, FILTER_COMM);
__generic_field(char *, comm, FILTER_COMM);
return ret; return ret;
} }
......
...@@ -1043,13 +1043,14 @@ static int init_pred(struct filter_parse_state *ps, ...@@ -1043,13 +1043,14 @@ static int init_pred(struct filter_parse_state *ps,
return -EINVAL; return -EINVAL;
} }
if (is_string_field(field)) { if (field->filter_type == FILTER_COMM) {
filter_build_regex(pred); filter_build_regex(pred);
if (!strcmp(field->name, "comm")) {
fn = filter_pred_comm; fn = filter_pred_comm;
pred->regex.field_len = TASK_COMM_LEN; pred->regex.field_len = TASK_COMM_LEN;
} else if (field->filter_type == FILTER_STATIC_STRING) { } else if (is_string_field(field)) {
filter_build_regex(pred);
if (field->filter_type == FILTER_STATIC_STRING) {
fn = filter_pred_string; fn = filter_pred_string;
pred->regex.field_len = field->size; pred->regex.field_len = field->size;
} else if (field->filter_type == FILTER_DYN_STRING) } else if (field->filter_type == FILTER_DYN_STRING)
...@@ -1072,7 +1073,7 @@ static int init_pred(struct filter_parse_state *ps, ...@@ -1072,7 +1073,7 @@ static int init_pred(struct filter_parse_state *ps,
} }
pred->val = val; pred->val = val;
if (!strcmp(field->name, "cpu")) if (field->filter_type == FILTER_CPU)
fn = filter_pred_cpu; fn = filter_pred_cpu;
else else
fn = select_comparison_fn(pred->op, field->size, fn = select_comparison_fn(pred->op, field->size,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment