Merge tag 'trace-v4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Apr 2015 18:27:36 +0000 (11:27 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Apr 2015 18:27:36 +0000 (11:27 -0700)
Pull tracing fixes from Steven Rostedt:
 "This adds three fixes for the tracing code.

  The first is a bug when ftrace_dump_on_oops is triggered in atomic
  context and function graph tracer is the tracer that is being
  reported.

  The second fix is bad parsing of the trace_events from the kernel
  command line, where it would ignore specific events if the system name
  is used with defining the event(it enables all events within the
  system).

  The last one is a fix to the TRACE_DEFINE_ENUM(), where a check was
  missing to see if the ptr was incremented to the end of the string,
  but the loop increments it again and can miss the nul delimiter to
  stop processing"

* tag 'trace-v4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  tracing: Fix possible out of bounds memory access when parsing enums
  tracing: Fix incorrect enabling of trace events by boot cmdline
  tracing: Handle ftrace_dump() atomic context in graph_trace_open()

1  2 
kernel/trace/trace_events.c
kernel/trace/trace_functions_graph.c

index 7da1dfeb322e696c3352300982bfc0ad96fdd98f,b49c107f82acbd0cc636838dd2e70a1e59eb1f71..3ab69fb72b85d2c4778dbb65683c73f437d309d2
@@@ -13,7 -13,7 +13,7 @@@
  #include <linux/workqueue.h>
  #include <linux/spinlock.h>
  #include <linux/kthread.h>
 -#include <linux/debugfs.h>
 +#include <linux/tracefs.h>
  #include <linux/uaccess.h>
  #include <linux/module.h>
  #include <linux/ctype.h>
@@@ -480,7 -480,7 +480,7 @@@ static void remove_subsystem(struct ftr
                return;
  
        if (!--dir->nr_events) {
 -              debugfs_remove_recursive(dir->entry);
 +              tracefs_remove_recursive(dir->entry);
                list_del(&dir->list);
                __put_system_dir(dir);
        }
@@@ -499,7 -499,7 +499,7 @@@ static void remove_event_file_dir(struc
                }
                spin_unlock(&dir->d_lock);
  
 -              debugfs_remove_recursive(dir);
 +              tracefs_remove_recursive(dir);
        }
  
        list_del(&file->list);
@@@ -565,6 -565,7 +565,7 @@@ static int __ftrace_set_clr_event(struc
  static int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set)
  {
        char *event = NULL, *sub = NULL, *match;
+       int ret;
  
        /*
         * The buf format can be <subsystem>:<event-name>
                        event = NULL;
        }
  
-       return __ftrace_set_clr_event(tr, match, sub, event, set);
+       ret = __ftrace_set_clr_event(tr, match, sub, event, set);
+       /* Put back the colon to allow this to be called again */
+       if (buf)
+               *(buf - 1) = ':';
+       return ret;
  }
  
  /**
@@@ -1526,7 -1533,7 +1533,7 @@@ event_subsystem_dir(struct trace_array 
        } else
                __get_system(system);
  
 -      dir->entry = debugfs_create_dir(name, parent);
 +      dir->entry = tracefs_create_dir(name, parent);
        if (!dir->entry) {
                pr_warn("Failed to create system directory %s\n", name);
                __put_system(system);
        dir->subsystem = system;
        file->system = dir;
  
 -      entry = debugfs_create_file("filter", 0644, dir->entry, dir,
 +      entry = tracefs_create_file("filter", 0644, dir->entry, dir,
                                    &ftrace_subsystem_filter_fops);
        if (!entry) {
                kfree(system->filter);
                system->filter = NULL;
 -              pr_warn("Could not create debugfs '%s/filter' entry\n", name);
 +              pr_warn("Could not create tracefs '%s/filter' entry\n", name);
        }
  
        trace_create_file("enable", 0644, dir->entry, dir,
@@@ -1585,9 -1592,9 +1592,9 @@@ event_create_dir(struct dentry *parent
                d_events = parent;
  
        name = ftrace_event_name(call);
 -      file->dir = debugfs_create_dir(name, d_events);
 +      file->dir = tracefs_create_dir(name, d_events);
        if (!file->dir) {
 -              pr_warn("Could not create debugfs '%s' directory\n", name);
 +              pr_warn("Could not create tracefs '%s' directory\n", name);
                return -1;
        }
  
@@@ -1753,6 -1760,8 +1760,8 @@@ static void update_event_printk(struct 
                                ptr++;
                                /* Check for alpha chars like ULL */
                        } while (isalnum(*ptr));
+                       if (!*ptr)
+                               break;
                        /*
                         * A number must have some kind of delimiter after
                         * it, and we can ignore that too.
                        do {
                                ptr++;
                        } while (isalnum(*ptr) || *ptr == '_');
+                       if (!*ptr)
+                               break;
                        /*
                         * If what comes after this variable is a '.' or
                         * '->' then we can continue to ignore that string.
                         */
                        if (*ptr == '.' || (ptr[0] == '-' && ptr[1] == '>')) {
                                ptr += *ptr == '.' ? 1 : 2;
+                               if (!*ptr)
+                                       break;
                                goto skip_more;
                        }
                        /*
@@@ -2347,7 -2360,7 +2360,7 @@@ static inline int register_event_cmds(v
  /*
   * The top level array has already had its ftrace_event_file
   * descriptors created in order to allow for early events to
 - * be recorded. This function is called after the debugfs has been
 + * be recorded. This function is called after the tracefs has been
   * initialized, and we now have to create the files associated
   * to the events.
   */
@@@ -2430,16 -2443,16 +2443,16 @@@ create_event_toplevel_files(struct dent
        struct dentry *d_events;
        struct dentry *entry;
  
 -      entry = debugfs_create_file("set_event", 0644, parent,
 +      entry = tracefs_create_file("set_event", 0644, parent,
                                    tr, &ftrace_set_event_fops);
        if (!entry) {
 -              pr_warn("Could not create debugfs 'set_event' entry\n");
 +              pr_warn("Could not create tracefs 'set_event' entry\n");
                return -ENOMEM;
        }
  
 -      d_events = debugfs_create_dir("events", parent);
 +      d_events = tracefs_create_dir("events", parent);
        if (!d_events) {
 -              pr_warn("Could not create debugfs 'events' directory\n");
 +              pr_warn("Could not create tracefs 'events' directory\n");
                return -ENOMEM;
        }
  
@@@ -2531,7 -2544,7 +2544,7 @@@ int event_trace_del_tracer(struct trace
  
        down_write(&trace_event_sem);
        __trace_remove_event_dirs(tr);
 -      debugfs_remove_recursive(tr->event_dir);
 +      tracefs_remove_recursive(tr->event_dir);
        up_write(&trace_event_sem);
  
        tr->event_dir = NULL;
@@@ -2653,10 -2666,10 +2666,10 @@@ static __init int event_trace_init(void
        if (IS_ERR(d_tracer))
                return 0;
  
 -      entry = debugfs_create_file("available_events", 0444, d_tracer,
 +      entry = tracefs_create_file("available_events", 0444, d_tracer,
                                    tr, &ftrace_avail_fops);
        if (!entry)
 -              pr_warn("Could not create debugfs 'available_events' entry\n");
 +              pr_warn("Could not create tracefs 'available_events' entry\n");
  
        if (trace_define_common_fields())
                pr_warn("tracing: Failed to allocate common fields");
index 9cfea4c6d314c6153d4986a55a89503671e2b1a4,b6fce365ef27569cb4b82ed762f0ec6b1dd3810d..a51e79688455edb5afb76f09ff2d70c0eae15ca5
@@@ -6,6 -6,7 +6,6 @@@
   * is Copyright (c) Steven Rostedt <srostedt@redhat.com>
   *
   */
 -#include <linux/debugfs.h>
  #include <linux/uaccess.h>
  #include <linux/ftrace.h>
  #include <linux/slab.h>
@@@ -150,7 -151,7 +150,7 @@@ ftrace_push_return_trace(unsigned long 
         * The curr_ret_stack is initialized to -1 and get increased
         * in this function.  So it can be less than -1 only if it was
         * filtered out via ftrace_graph_notrace_addr() which can be
 -       * set from set_graph_notrace file in debugfs by user.
 +       * set from set_graph_notrace file in tracefs by user.
         */
        if (current->curr_ret_stack < -1)
                return -EBUSY;
@@@ -1308,15 -1309,19 +1308,19 @@@ void graph_trace_open(struct trace_iter
  {
        /* pid and depth on the last trace processed */
        struct fgraph_data *data;
+       gfp_t gfpflags;
        int cpu;
  
        iter->private = NULL;
  
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       /* We can be called in atomic context via ftrace_dump() */
+       gfpflags = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL;
+       data = kzalloc(sizeof(*data), gfpflags);
        if (!data)
                goto out_err;
  
-       data->cpu_data = alloc_percpu(struct fgraph_cpu_data);
+       data->cpu_data = alloc_percpu_gfp(struct fgraph_cpu_data, gfpflags);
        if (!data->cpu_data)
                goto out_err_free;
  
@@@ -1431,7 -1436,7 +1435,7 @@@ static const struct file_operations gra
        .llseek         = generic_file_llseek,
  };
  
 -static __init int init_graph_debugfs(void)
 +static __init int init_graph_tracefs(void)
  {
        struct dentry *d_tracer;
  
  
        return 0;
  }
 -fs_initcall(init_graph_debugfs);
 +fs_initcall(init_graph_tracefs);
  
  static __init int init_graph_trace(void)
  {