Merge branch 'tracing/urgent' into tracing/core
authorIngo Molnar <mingo@elte.hu>
Thu, 1 Oct 2009 09:20:33 +0000 (11:20 +0200)
committerIngo Molnar <mingo@elte.hu>
Thu, 1 Oct 2009 09:20:48 +0000 (11:20 +0200)
Merge reason: Pick up latest fixes and update to latest upstream.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
1  2 
kernel/trace/ftrace.c
kernel/trace/trace.h
kernel/trace/trace_events.c

diff --combined kernel/trace/ftrace.c
index ddf23a225b5269d66371aab7b13bdd3f67c9baf7,3724756e41ca9771d311101a38d2f408d416ef6a..9a72853a8f0acb22002511546deddc4f9c7cfe23
@@@ -225,7 -225,11 +225,11 @@@ static void ftrace_update_pid_func(void
        if (ftrace_trace_function == ftrace_stub)
                return;
  
+ #ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
        func = ftrace_trace_function;
+ #else
+       func = __ftrace_trace_function;
+ #endif
  
        if (ftrace_pid_trace) {
                set_ftrace_pid_function(func);
@@@ -1520,7 -1524,7 +1524,7 @@@ static int t_show(struct seq_file *m, v
        return 0;
  }
  
- static struct seq_operations show_ftrace_seq_ops = {
+ static const struct seq_operations show_ftrace_seq_ops = {
        .start = t_start,
        .next = t_next,
        .stop = t_stop,
@@@ -1621,8 -1625,10 +1625,10 @@@ ftrace_regex_open(struct inode *inode, 
                if (!ret) {
                        struct seq_file *m = file->private_data;
                        m->private = iter;
-               } else
+               } else {
+                       trace_parser_put(&iter->parser);
                        kfree(iter);
+               }
        } else
                file->private_data = iter;
        mutex_unlock(&ftrace_regex_lock);
@@@ -1655,6 -1661,60 +1661,6 @@@ ftrace_regex_lseek(struct file *file, l
        return ret;
  }
  
 -enum {
 -      MATCH_FULL,
 -      MATCH_FRONT_ONLY,
 -      MATCH_MIDDLE_ONLY,
 -      MATCH_END_ONLY,
 -};
 -
 -/*
 - * (static function - no need for kernel doc)
 - *
 - * Pass in a buffer containing a glob and this function will
 - * set search to point to the search part of the buffer and
 - * return the type of search it is (see enum above).
 - * This does modify buff.
 - *
 - * Returns enum type.
 - *  search returns the pointer to use for comparison.
 - *  not returns 1 if buff started with a '!'
 - *     0 otherwise.
 - */
 -static int
 -ftrace_setup_glob(char *buff, int len, char **search, int *not)
 -{
 -      int type = MATCH_FULL;
 -      int i;
 -
 -      if (buff[0] == '!') {
 -              *not = 1;
 -              buff++;
 -              len--;
 -      } else
 -              *not = 0;
 -
 -      *search = buff;
 -
 -      for (i = 0; i < len; i++) {
 -              if (buff[i] == '*') {
 -                      if (!i) {
 -                              *search = buff + 1;
 -                              type = MATCH_END_ONLY;
 -                      } else {
 -                              if (type == MATCH_END_ONLY)
 -                                      type = MATCH_MIDDLE_ONLY;
 -                              else
 -                                      type = MATCH_FRONT_ONLY;
 -                              buff[i] = 0;
 -                              break;
 -                      }
 -              }
 -      }
 -
 -      return type;
 -}
 -
  static int ftrace_match(char *str, char *regex, int len, int type)
  {
        int matched = 0;
@@@ -1703,7 -1763,7 +1709,7 @@@ static void ftrace_match_records(char *
        int not;
  
        flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
 -      type = ftrace_setup_glob(buff, len, &search, &not);
 +      type = filter_parse_regex(buff, len, &search, &not);
  
        search_len = strlen(search);
  
@@@ -1771,7 -1831,7 +1777,7 @@@ static void ftrace_match_module_records
        }
  
        if (strlen(buff)) {
 -              type = ftrace_setup_glob(buff, strlen(buff), &search, &not);
 +              type = filter_parse_regex(buff, strlen(buff), &search, &not);
                search_len = strlen(search);
        }
  
@@@ -1936,7 -1996,7 +1942,7 @@@ register_ftrace_function_probe(char *gl
        int count = 0;
        char *search;
  
 -      type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
 +      type = filter_parse_regex(glob, strlen(glob), &search, &not);
        len = strlen(search);
  
        /* we do not support '!' for function probes */
@@@ -2013,7 -2073,7 +2019,7 @@@ __unregister_ftrace_function_probe(cha
        else if (glob) {
                int not;
  
 -              type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
 +              type = filter_parse_regex(glob, strlen(glob), &search, &not);
                len = strlen(search);
  
                /* we do not support '!' for function probes */
@@@ -2148,7 -2208,7 +2154,7 @@@ ftrace_regex_write(struct file *file, c
        struct trace_parser *parser;
        ssize_t ret, read;
  
-       if (!cnt || cnt < 0)
+       if (!cnt)
                return 0;
  
        mutex_lock(&ftrace_regex_lock);
        parser = &iter->parser;
        read = trace_get_user(parser, ubuf, cnt, ppos);
  
-       if (trace_parser_loaded(parser) &&
+       if (read >= 0 && trace_parser_loaded(parser) &&
            !trace_parser_cont(parser)) {
                ret = ftrace_process_regex(parser->buffer,
                                           parser->idx, enable);
@@@ -2360,11 -2420,9 +2366,9 @@@ unsigned long ftrace_graph_funcs[FTRACE
  static void *
  __g_next(struct seq_file *m, loff_t *pos)
  {
-       unsigned long *array = m->private;
        if (*pos >= ftrace_graph_count)
                return NULL;
-       return &array[*pos];
+       return &ftrace_graph_funcs[*pos];
  }
  
  static void *
@@@ -2407,7 -2465,7 +2411,7 @@@ static int g_show(struct seq_file *m, v
        return 0;
  }
  
- static struct seq_operations ftrace_graph_seq_ops = {
+ static const struct seq_operations ftrace_graph_seq_ops = {
        .start = g_start,
        .next = g_next,
        .stop = g_stop,
@@@ -2428,16 -2486,10 +2432,10 @@@ ftrace_graph_open(struct inode *inode, 
                ftrace_graph_count = 0;
                memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs));
        }
+       mutex_unlock(&graph_lock);
  
-       if (file->f_mode & FMODE_READ) {
+       if (file->f_mode & FMODE_READ)
                ret = seq_open(file, &ftrace_graph_seq_ops);
-               if (!ret) {
-                       struct seq_file *m = file->private_data;
-                       m->private = ftrace_graph_funcs;
-               }
-       } else
-               file->private_data = ftrace_graph_funcs;
-       mutex_unlock(&graph_lock);
  
        return ret;
  }
@@@ -2466,7 -2518,7 +2464,7 @@@ ftrace_set_func(unsigned long *array, i
                return -ENODEV;
  
        /* decode regex */
 -      type = ftrace_setup_glob(buffer, strlen(buffer), &search, &not);
 +      type = filter_parse_regex(buffer, strlen(buffer), &search, &not);
        if (not)
                return -EINVAL;
  
@@@ -2506,9 -2558,7 +2504,7 @@@ ftrace_graph_write(struct file *file, c
                   size_t cnt, loff_t *ppos)
  {
        struct trace_parser parser;
-       unsigned long *array;
-       size_t read = 0;
-       ssize_t ret;
+       ssize_t read, ret;
  
        if (!cnt || cnt < 0)
                return 0;
  
        if (ftrace_graph_count >= FTRACE_GRAPH_MAX_FUNCS) {
                ret = -EBUSY;
-               goto out;
+               goto out_unlock;
        }
  
-       if (file->f_mode & FMODE_READ) {
-               struct seq_file *m = file->private_data;
-               array = m->private;
-       } else
-               array = file->private_data;
        if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) {
                ret = -ENOMEM;
-               goto out;
+               goto out_unlock;
        }
  
        read = trace_get_user(&parser, ubuf, cnt, ppos);
  
-       if (trace_parser_loaded((&parser))) {
+       if (read >= 0 && trace_parser_loaded((&parser))) {
                parser.buffer[parser.idx] = 0;
  
                /* we allow only one expression at a time */
-               ret = ftrace_set_func(array, &ftrace_graph_count,
+               ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count,
                                        parser.buffer);
                if (ret)
-                       goto out;
+                       goto out_free;
        }
  
        ret = read;
-  out:
+ out_free:
        trace_parser_put(&parser);
+ out_unlock:
        mutex_unlock(&graph_lock);
  
        return ret;
@@@ -2976,7 -3022,7 +2968,7 @@@ int unregister_ftrace_function(struct f
  
  int
  ftrace_enable_sysctl(struct ctl_table *table, int write,
-                    struct file *file, void __user *buffer, size_t *lenp,
+                    void __user *buffer, size_t *lenp,
                     loff_t *ppos)
  {
        int ret;
  
        mutex_lock(&ftrace_lock);
  
-       ret  = proc_dointvec(table, write, file, buffer, lenp, ppos);
+       ret  = proc_dointvec(table, write, buffer, lenp, ppos);
  
        if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled))
                goto out;
diff --combined kernel/trace/trace.h
index db6b83edd49bf62851953de5dafd9663cdc8f389,405cb850b75d9a308d04d198946e9b0e8da21a39..365fb19d9e111c349717fda69f4511d2aa85c0f1
@@@ -11,7 -11,6 +11,6 @@@
  #include <linux/ftrace.h>
  #include <trace/boot.h>
  #include <linux/kmemtrace.h>
- #include <trace/power.h>
  
  #include <linux/trace_seq.h>
  #include <linux/ftrace_event.h>
@@@ -37,7 -36,6 +36,6 @@@ enum trace_type 
        TRACE_HW_BRANCHES,
        TRACE_KMEM_ALLOC,
        TRACE_KMEM_FREE,
-       TRACE_POWER,
        TRACE_BLK,
  
        __TRACE_LAST_TYPE,
@@@ -207,7 -205,6 +205,6 @@@ extern void __ftrace_bad_type(void)
                IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry,      \
                          TRACE_GRAPH_RET);             \
                IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\
-               IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \
                IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry,       \
                          TRACE_KMEM_ALLOC);    \
                IF_ASSIGN(var, ent, struct kmemtrace_free_entry,        \
@@@ -702,40 -699,22 +699,40 @@@ struct event_subsystem 
  };
  
  struct filter_pred;
 +struct regex;
  
  typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event,
                                 int val1, int val2);
  
 +typedef int (*regex_match_func)(char *str, struct regex *r, int len);
 +
 +enum regex_type {
 +      MATCH_FULL,
 +      MATCH_FRONT_ONLY,
 +      MATCH_MIDDLE_ONLY,
 +      MATCH_END_ONLY,
 +};
 +
 +struct regex {
 +      char                    pattern[MAX_FILTER_STR_VAL];
 +      int                     len;
 +      int                     field_len;
 +      regex_match_func        match;
 +};
 +
  struct filter_pred {
 -      filter_pred_fn_t fn;
 -      u64 val;
 -      char str_val[MAX_FILTER_STR_VAL];
 -      int str_len;
 -      char *field_name;
 -      int offset;
 -      int not;
 -      int op;
 -      int pop_n;
 +      filter_pred_fn_t        fn;
 +      u64                     val;
 +      struct regex            regex;
 +      char                    *field_name;
 +      int                     offset;
 +      int                     not;
 +      int                     op;
 +      int                     pop_n;
  };
  
 +extern enum regex_type
 +filter_parse_regex(char *buff, int len, char **search, int *not);
  extern void print_event_filter(struct ftrace_event_call *call,
                               struct trace_seq *s);
  extern int apply_event_filter(struct ftrace_event_call *call,
index 8c91b7c8f04731e488bb1131538d378176c8d1bf,d128f65778e69654207c6d8d7b987bc7837f7541..5e9ffc33f6db7b0e0d992b2de0ce52f380c33476
@@@ -232,10 -232,9 +232,9 @@@ ftrace_event_write(struct file *file, c
                   size_t cnt, loff_t *ppos)
  {
        struct trace_parser parser;
-       size_t read = 0;
-       ssize_t ret;
+       ssize_t read, ret;
  
-       if (!cnt || cnt < 0)
+       if (!cnt)
                return 0;
  
        ret = tracing_update_buffers();
  
        read = trace_get_user(&parser, ubuf, cnt, ppos);
  
-       if (trace_parser_loaded((&parser))) {
+       if (read >= 0 && trace_parser_loaded((&parser))) {
                int set = 1;
  
                if (*parser.buffer == '!')
  static void *
  t_next(struct seq_file *m, void *v, loff_t *pos)
  {
-       struct list_head *list = m->private;
-       struct ftrace_event_call *call;
+       struct ftrace_event_call *call = v;
  
        (*pos)++;
  
-       for (;;) {
-               if (list == &ftrace_events)
-                       return NULL;
-               call = list_entry(list, struct ftrace_event_call, list);
+       list_for_each_entry_continue(call, &ftrace_events, list) {
                /*
                 * The ftrace subsystem is for showing formats only.
                 * They can not be enabled or disabled via the event files.
                 */
                if (call->regfunc)
-                       break;
-               list = list->next;
+                       return call;
        }
  
-       m->private = list->next;
-       return call;
+       return NULL;
  }
  
  static void *t_start(struct seq_file *m, loff_t *pos)
  {
-       struct ftrace_event_call *call = NULL;
+       struct ftrace_event_call *call;
        loff_t l;
  
        mutex_lock(&event_mutex);
  
-       m->private = ftrace_events.next;
+       call = list_entry(&ftrace_events, struct ftrace_event_call, list);
        for (l = 0; l <= *pos; ) {
-               call = t_next(m, NULL, &l);
+               call = t_next(m, call, &l);
                if (!call)
                        break;
        }
  static void *
  s_next(struct seq_file *m, void *v, loff_t *pos)
  {
-       struct list_head *list = m->private;
-       struct ftrace_event_call *call;
+       struct ftrace_event_call *call = v;
  
        (*pos)++;
  
-  retry:
-       if (list == &ftrace_events)
-               return NULL;
-       call = list_entry(list, struct ftrace_event_call, list);
-       if (!call->enabled) {
-               list = list->next;
-               goto retry;
+       list_for_each_entry_continue(call, &ftrace_events, list) {
+               if (call->enabled)
+                       return call;
        }
  
-       m->private = list->next;
-       return call;
+       return NULL;
  }
  
  static void *s_start(struct seq_file *m, loff_t *pos)
  {
-       struct ftrace_event_call *call = NULL;
+       struct ftrace_event_call *call;
        loff_t l;
  
        mutex_lock(&event_mutex);
  
-       m->private = ftrace_events.next;
+       call = list_entry(&ftrace_events, struct ftrace_event_call, list);
        for (l = 0; l <= *pos; ) {
-               call = s_next(m, NULL, &l);
+               call = s_next(m, call, &l);
                if (!call)
                        break;
        }
@@@ -898,9 -878,9 +878,9 @@@ event_subsystem_dir(const char *name, s
                           "'%s/filter' entry\n", name);
        }
  
 -      entry = trace_create_file("enable", 0644, system->entry,
 -                                (void *)system->name,
 -                                &ftrace_system_enable_fops);
 +      trace_create_file("enable", 0644, system->entry,
 +                        (void *)system->name,
 +                        &ftrace_system_enable_fops);
  
        return system->entry;
  }
@@@ -912,6 -892,7 +892,6 @@@ event_create_dir(struct ftrace_event_ca
                 const struct file_operations *filter,
                 const struct file_operations *format)
  {
 -      struct dentry *entry;
        int ret;
  
        /*
        }
  
        if (call->regfunc)
 -              entry = trace_create_file("enable", 0644, call->dir, call,
 -                                        enable);
 +              trace_create_file("enable", 0644, call->dir, call,
 +                                enable);
  
        if (call->id && call->profile_enable)
 -              entry = trace_create_file("id", 0444, call->dir, call,
 -                                        id);
 +              trace_create_file("id", 0444, call->dir, call,
 +                                id);
  
        if (call->define_fields) {
                ret = call->define_fields(call);
                                   " events/%s\n", call->name);
                        return ret;
                }
 -              entry = trace_create_file("filter", 0644, call->dir, call,
 -                                        filter);
 +              trace_create_file("filter", 0644, call->dir, call,
 +                                filter);
        }
  
        /* A trace may not want to export its format */
        if (!call->show_format)
                return 0;
  
 -      entry = trace_create_file("format", 0444, call->dir, call,
 -                                format);
 +      trace_create_file("format", 0444, call->dir, call,
 +                        format);
  
        return 0;
  }