These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / kernel / trace / trace_events_filter.c
index 52adf02..6816302 100644 (file)
@@ -252,6 +252,50 @@ static int filter_pred_strloc(struct filter_pred *pred, void *event)
        return match;
 }
 
+/* Filter predicate for CPUs. */
+static int filter_pred_cpu(struct filter_pred *pred, void *event)
+{
+       int cpu, cmp;
+       int match = 0;
+
+       cpu = raw_smp_processor_id();
+       cmp = pred->val;
+
+       switch (pred->op) {
+       case OP_EQ:
+               match = cpu == cmp;
+               break;
+       case OP_LT:
+               match = cpu < cmp;
+               break;
+       case OP_LE:
+               match = cpu <= cmp;
+               break;
+       case OP_GT:
+               match = cpu > cmp;
+               break;
+       case OP_GE:
+               match = cpu >= cmp;
+               break;
+       default:
+               break;
+       }
+
+       return !!match == !pred->not;
+}
+
+/* Filter predicate for COMM. */
+static int filter_pred_comm(struct filter_pred *pred, void *event)
+{
+       int cmp, match;
+
+       cmp = pred->regex.match(current->comm, &pred->regex,
+                               pred->regex.field_len);
+       match = cmp ^ pred->not;
+
+       return match;
+}
+
 static int filter_pred_none(struct filter_pred *pred, void *event)
 {
        return 0;
@@ -643,7 +687,7 @@ static void append_filter_err(struct filter_parse_state *ps,
        free_page((unsigned long) buf);
 }
 
-static inline struct event_filter *event_filter(struct ftrace_event_file *file)
+static inline struct event_filter *event_filter(struct trace_event_file *file)
 {
        if (file->event_call->flags & TRACE_EVENT_FL_USE_CALL_FILTER)
                return file->event_call->filter;
@@ -652,7 +696,7 @@ static inline struct event_filter *event_filter(struct ftrace_event_file *file)
 }
 
 /* caller must hold event_mutex */
-void print_event_filter(struct ftrace_event_file *file, struct trace_seq *s)
+void print_event_filter(struct trace_event_file *file, struct trace_seq *s)
 {
        struct event_filter *filter = event_filter(file);
 
@@ -780,14 +824,14 @@ static void __free_preds(struct event_filter *filter)
        filter->n_preds = 0;
 }
 
-static void filter_disable(struct ftrace_event_file *file)
+static void filter_disable(struct trace_event_file *file)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
 
        if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER)
                call->flags &= ~TRACE_EVENT_FL_FILTERED;
        else
-               file->flags &= ~FTRACE_EVENT_FL_FILTERED;
+               file->flags &= ~EVENT_FILE_FL_FILTERED;
 }
 
 static void __free_filter(struct event_filter *filter)
@@ -837,9 +881,9 @@ static int __alloc_preds(struct event_filter *filter, int n_preds)
        return 0;
 }
 
-static inline void __remove_filter(struct ftrace_event_file *file)
+static inline void __remove_filter(struct trace_event_file *file)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
 
        filter_disable(file);
        if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER)
@@ -848,10 +892,10 @@ static inline void __remove_filter(struct ftrace_event_file *file)
                remove_filter_string(file->filter);
 }
 
-static void filter_free_subsystem_preds(struct ftrace_subsystem_dir *dir,
+static void filter_free_subsystem_preds(struct trace_subsystem_dir *dir,
                                        struct trace_array *tr)
 {
-       struct ftrace_event_file *file;
+       struct trace_event_file *file;
 
        list_for_each_entry(file, &tr->events, list) {
                if (file->system != dir)
@@ -860,9 +904,9 @@ static void filter_free_subsystem_preds(struct ftrace_subsystem_dir *dir,
        }
 }
 
-static inline void __free_subsystem_filter(struct ftrace_event_file *file)
+static inline void __free_subsystem_filter(struct trace_event_file *file)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
 
        if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER) {
                __free_filter(call->filter);
@@ -873,10 +917,10 @@ static inline void __free_subsystem_filter(struct ftrace_event_file *file)
        }
 }
 
-static void filter_free_subsystem_filters(struct ftrace_subsystem_dir *dir,
+static void filter_free_subsystem_filters(struct trace_subsystem_dir *dir,
                                          struct trace_array *tr)
 {
-       struct ftrace_event_file *file;
+       struct trace_event_file *file;
 
        list_for_each_entry(file, &tr->events, list) {
                if (file->system != dir)
@@ -929,15 +973,15 @@ static bool is_string_field(struct ftrace_event_field *field)
               field->filter_type == FILTER_PTR_STRING;
 }
 
-static int is_legal_op(struct ftrace_event_field *field, int op)
+static bool is_legal_op(struct ftrace_event_field *field, int op)
 {
        if (is_string_field(field) &&
            (op != OP_EQ && op != OP_NE && op != OP_GLOB))
-               return 0;
+               return false;
        if (!is_string_field(field) && op == OP_GLOB)
-               return 0;
+               return false;
 
-       return 1;
+       return true;
 }
 
 static filter_pred_fn_t select_comparison_fn(int op, int field_size,
@@ -999,7 +1043,11 @@ static int init_pred(struct filter_parse_state *ps,
                return -EINVAL;
        }
 
-       if (is_string_field(field)) {
+       if (field->filter_type == FILTER_COMM) {
+               filter_build_regex(pred);
+               fn = filter_pred_comm;
+               pred->regex.field_len = TASK_COMM_LEN;
+       } else if (is_string_field(field)) {
                filter_build_regex(pred);
 
                if (field->filter_type == FILTER_STATIC_STRING) {
@@ -1025,7 +1073,10 @@ static int init_pred(struct filter_parse_state *ps,
                }
                pred->val = val;
 
-               fn = select_comparison_fn(pred->op, field->size,
+               if (field->filter_type == FILTER_CPU)
+                       fn = filter_pred_cpu;
+               else
+                       fn = select_comparison_fn(pred->op, field->size,
                                          field->is_signed);
                if (!fn) {
                        parse_error(ps, FILT_ERR_INVALID_OP, 0);
@@ -1342,7 +1393,7 @@ parse_operand:
 }
 
 static struct filter_pred *create_pred(struct filter_parse_state *ps,
-                                      struct ftrace_event_call *call,
+                                      struct trace_event_call *call,
                                       int op, char *operand1, char *operand2)
 {
        struct ftrace_event_field *field;
@@ -1564,7 +1615,7 @@ static int fold_pred_tree(struct event_filter *filter,
                              filter->preds);
 }
 
-static int replace_preds(struct ftrace_event_call *call,
+static int replace_preds(struct trace_event_call *call,
                         struct event_filter *filter,
                         struct filter_parse_state *ps,
                         bool dry_run)
@@ -1677,20 +1728,20 @@ fail:
        return err;
 }
 
-static inline void event_set_filtered_flag(struct ftrace_event_file *file)
+static inline void event_set_filtered_flag(struct trace_event_file *file)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
 
        if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER)
                call->flags |= TRACE_EVENT_FL_FILTERED;
        else
-               file->flags |= FTRACE_EVENT_FL_FILTERED;
+               file->flags |= EVENT_FILE_FL_FILTERED;
 }
 
-static inline void event_set_filter(struct ftrace_event_file *file,
+static inline void event_set_filter(struct trace_event_file *file,
                                    struct event_filter *filter)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
 
        if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER)
                rcu_assign_pointer(call->filter, filter);
@@ -1698,9 +1749,9 @@ static inline void event_set_filter(struct ftrace_event_file *file,
                rcu_assign_pointer(file->filter, filter);
 }
 
-static inline void event_clear_filter(struct ftrace_event_file *file)
+static inline void event_clear_filter(struct trace_event_file *file)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
 
        if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER)
                RCU_INIT_POINTER(call->filter, NULL);
@@ -1709,33 +1760,33 @@ static inline void event_clear_filter(struct ftrace_event_file *file)
 }
 
 static inline void
-event_set_no_set_filter_flag(struct ftrace_event_file *file)
+event_set_no_set_filter_flag(struct trace_event_file *file)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
 
        if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER)
                call->flags |= TRACE_EVENT_FL_NO_SET_FILTER;
        else
-               file->flags |= FTRACE_EVENT_FL_NO_SET_FILTER;
+               file->flags |= EVENT_FILE_FL_NO_SET_FILTER;
 }
 
 static inline void
-event_clear_no_set_filter_flag(struct ftrace_event_file *file)
+event_clear_no_set_filter_flag(struct trace_event_file *file)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
 
        if (call->flags & TRACE_EVENT_FL_USE_CALL_FILTER)
                call->flags &= ~TRACE_EVENT_FL_NO_SET_FILTER;
        else
-               file->flags &= ~FTRACE_EVENT_FL_NO_SET_FILTER;
+               file->flags &= ~EVENT_FILE_FL_NO_SET_FILTER;
 }
 
 static inline bool
-event_no_set_filter_flag(struct ftrace_event_file *file)
+event_no_set_filter_flag(struct trace_event_file *file)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
 
-       if (file->flags & FTRACE_EVENT_FL_NO_SET_FILTER)
+       if (file->flags & EVENT_FILE_FL_NO_SET_FILTER)
                return true;
 
        if ((call->flags & TRACE_EVENT_FL_USE_CALL_FILTER) &&
@@ -1750,12 +1801,12 @@ struct filter_list {
        struct event_filter     *filter;
 };
 
-static int replace_system_preds(struct ftrace_subsystem_dir *dir,
+static int replace_system_preds(struct trace_subsystem_dir *dir,
                                struct trace_array *tr,
                                struct filter_parse_state *ps,
                                char *filter_string)
 {
-       struct ftrace_event_file *file;
+       struct trace_event_file *file;
        struct filter_list *filter_item;
        struct filter_list *tmp;
        LIST_HEAD(filter_list);
@@ -1899,8 +1950,8 @@ static void create_filter_finish(struct filter_parse_state *ps)
 }
 
 /**
- * create_filter - create a filter for a ftrace_event_call
- * @call: ftrace_event_call to create a filter for
+ * create_filter - create a filter for a trace_event_call
+ * @call: trace_event_call to create a filter for
  * @filter_str: filter string
  * @set_str: remember @filter_str and enable detailed error in filter
  * @filterp: out param for created filter (always updated on return)
@@ -1914,7 +1965,7 @@ static void create_filter_finish(struct filter_parse_state *ps)
  * information if @set_str is %true and the caller is responsible for
  * freeing it.
  */
-static int create_filter(struct ftrace_event_call *call,
+static int create_filter(struct trace_event_call *call,
                         char *filter_str, bool set_str,
                         struct event_filter **filterp)
 {
@@ -1934,7 +1985,7 @@ static int create_filter(struct ftrace_event_call *call,
        return err;
 }
 
-int create_event_filter(struct ftrace_event_call *call,
+int create_event_filter(struct trace_event_call *call,
                        char *filter_str, bool set_str,
                        struct event_filter **filterp)
 {
@@ -1950,7 +2001,7 @@ int create_event_filter(struct ftrace_event_call *call,
  * Identical to create_filter() except that it creates a subsystem filter
  * and always remembers @filter_str.
  */
-static int create_system_filter(struct ftrace_subsystem_dir *dir,
+static int create_system_filter(struct trace_subsystem_dir *dir,
                                struct trace_array *tr,
                                char *filter_str, struct event_filter **filterp)
 {
@@ -1976,9 +2027,9 @@ static int create_system_filter(struct ftrace_subsystem_dir *dir,
 }
 
 /* caller must hold event_mutex */
-int apply_event_filter(struct ftrace_event_file *file, char *filter_string)
+int apply_event_filter(struct trace_event_file *file, char *filter_string)
 {
-       struct ftrace_event_call *call = file->event_call;
+       struct trace_event_call *call = file->event_call;
        struct event_filter *filter;
        int err;
 
@@ -2027,7 +2078,7 @@ int apply_event_filter(struct ftrace_event_file *file, char *filter_string)
        return err;
 }
 
-int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir,
+int apply_subsystem_event_filter(struct trace_subsystem_dir *dir,
                                 char *filter_string)
 {
        struct event_subsystem *system = dir->subsystem;
@@ -2090,7 +2141,7 @@ struct function_filter_data {
 static char **
 ftrace_function_filter_re(char *buf, int len, int *count)
 {
-       char *str, *sep, **re;
+       char *str, **re;
 
        str = kstrndup(buf, len, GFP_KERNEL);
        if (!str)
@@ -2100,8 +2151,7 @@ ftrace_function_filter_re(char *buf, int len, int *count)
         * The argv_split function takes white space
         * as a separator, so convert ',' into spaces.
         */
-       while ((sep = strchr(str, ',')))
-               *sep = ' ';
+       strreplace(str, ',', ' ');
 
        re = argv_split(GFP_KERNEL, str, count);
        kfree(str);
@@ -2227,7 +2277,7 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,
 {
        int err;
        struct event_filter *filter;
-       struct ftrace_event_call *call;
+       struct trace_event_call *call;
 
        mutex_lock(&event_mutex);
 
@@ -2283,7 +2333,7 @@ out_unlock:
 
 static struct test_filter_data_t {
        char *filter;
-       struct ftrace_raw_ftrace_test_filter rec;
+       struct trace_event_raw_ftrace_test_filter rec;
        int match;
        char *not_visited;
 } test_filter_data[] = {