Merge branch 'linux-linaro-lsk-v4.4' into linux-linaro-lsk-v4.4-android
[firefly-linux-kernel-4.4.55.git] / kernel / trace / trace.c
index 2198a630ef5826a30e51a2974d472b078273f80c..dd4d86ae8e213aafe5814aa00ffbab01c3cdd1c8 100644 (file)
@@ -100,8 +100,6 @@ static DEFINE_PER_CPU(bool, trace_cmdline_save);
  */
 static int tracing_disabled = 1;
 
-DEFINE_PER_CPU(int, ftrace_cpu_disabled);
-
 cpumask_var_t __read_mostly    tracing_buffer_mask;
 
 /*
@@ -1354,6 +1352,7 @@ void tracing_reset_all_online_cpus(void)
 
 #define SAVED_CMDLINES_DEFAULT 128
 #define NO_CMDLINE_MAP UINT_MAX
+static unsigned saved_tgids[SAVED_CMDLINES_DEFAULT];
 static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 struct saved_cmdlines_buffer {
        unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
@@ -1592,7 +1591,7 @@ static int trace_save_cmdline(struct task_struct *tsk)
        }
 
        set_cmdline(idx, tsk->comm);
-
+       saved_tgids[idx] = tsk->tgid;
        arch_spin_unlock(&trace_cmdline_lock);
 
        return 1;
@@ -1635,6 +1634,25 @@ void trace_find_cmdline(int pid, char comm[])
        preempt_enable();
 }
 
+int trace_find_tgid(int pid)
+{
+       unsigned map;
+       int tgid;
+
+       preempt_disable();
+       arch_spin_lock(&trace_cmdline_lock);
+       map = savedcmd->map_pid_to_cmdline[pid];
+       if (map != NO_CMDLINE_MAP)
+               tgid = saved_tgids[map];
+       else
+               tgid = -1;
+
+       arch_spin_unlock(&trace_cmdline_lock);
+       preempt_enable();
+
+       return tgid;
+}
+
 void tracing_record_cmdline(struct task_struct *tsk)
 {
        if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on())
@@ -1753,7 +1771,7 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
 {
        __buffer_unlock_commit(buffer, event);
 
-       ftrace_trace_stack(tr, buffer, flags, 6, pc, regs);
+       ftrace_trace_stack(tr, buffer, flags, 0, pc, regs);
        ftrace_trace_userstack(buffer, flags, pc);
 }
 EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit_regs);
@@ -1775,10 +1793,6 @@ trace_function(struct trace_array *tr,
        struct ring_buffer_event *event;
        struct ftrace_entry *entry;
 
-       /* If we are reading the ring buffer, don't trace */
-       if (unlikely(__this_cpu_read(ftrace_cpu_disabled)))
-               return;
-
        event = trace_buffer_lock_reserve(buffer, TRACE_FN, sizeof(*entry),
                                          flags, pc);
        if (!event)
@@ -2589,6 +2603,13 @@ static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m)
                    "#              | |       |          |         |\n");
 }
 
+static void print_func_help_header_tgid(struct trace_buffer *buf, struct seq_file *m)
+{
+       print_event_info(buf, m);
+       seq_puts(m, "#           TASK-PID    TGID   CPU#      TIMESTAMP  FUNCTION\n");
+       seq_puts(m, "#              | |        |      |          |         |\n");
+}
+
 static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m)
 {
        print_event_info(buf, m);
@@ -2601,6 +2622,18 @@ static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file
                    "#              | |       |   ||||       |         |\n");
 }
 
+static void print_func_help_header_irq_tgid(struct trace_buffer *buf, struct seq_file *m)
+{
+       print_event_info(buf, m);
+       seq_puts(m, "#                                      _-----=> irqs-off\n");
+       seq_puts(m, "#                                     / _----=> need-resched\n");
+       seq_puts(m, "#                                    | / _---=> hardirq/softirq\n");
+       seq_puts(m, "#                                    || / _--=> preempt-depth\n");
+       seq_puts(m, "#                                    ||| /     delay\n");
+       seq_puts(m, "#           TASK-PID    TGID   CPU#  ||||    TIMESTAMP  FUNCTION\n");
+       seq_puts(m, "#              | |        |      |   ||||       |         |\n");
+}
+
 void
 print_trace_header(struct seq_file *m, struct trace_iterator *iter)
 {
@@ -2913,9 +2946,15 @@ void trace_default_header(struct seq_file *m)
        } else {
                if (!(trace_flags & TRACE_ITER_VERBOSE)) {
                        if (trace_flags & TRACE_ITER_IRQ_INFO)
-                               print_func_help_header_irq(iter->trace_buffer, m);
+                               if (trace_flags & TRACE_ITER_TGID)
+                                       print_func_help_header_irq_tgid(iter->trace_buffer, m);
+                               else
+                                       print_func_help_header_irq(iter->trace_buffer, m);
                        else
-                               print_func_help_header(iter->trace_buffer, m);
+                               if (trace_flags & TRACE_ITER_TGID)
+                                       print_func_help_header_tgid(iter->trace_buffer, m);
+                               else
+                                       print_func_help_header(iter->trace_buffer, m);
                }
        }
 }
@@ -4166,6 +4205,50 @@ static void trace_insert_enum_map(struct module *mod,
        trace_insert_enum_map_file(mod, start, len);
 }
 
+static ssize_t
+tracing_saved_tgids_read(struct file *file, char __user *ubuf,
+                               size_t cnt, loff_t *ppos)
+{
+       char *file_buf;
+       char *buf;
+       int len = 0;
+       int pid;
+       int i;
+
+       file_buf = kmalloc(SAVED_CMDLINES_DEFAULT*(16+1+16), GFP_KERNEL);
+       if (!file_buf)
+               return -ENOMEM;
+
+       buf = file_buf;
+
+       for (i = 0; i < SAVED_CMDLINES_DEFAULT; i++) {
+               int tgid;
+               int r;
+
+               pid = savedcmd->map_cmdline_to_pid[i];
+               if (pid == -1 || pid == NO_CMDLINE_MAP)
+                       continue;
+
+               tgid = trace_find_tgid(pid);
+               r = sprintf(buf, "%d %d\n", pid, tgid);
+               buf += r;
+               len += r;
+       }
+
+       len = simple_read_from_buffer(ubuf, cnt, ppos,
+                                     file_buf, len);
+
+       kfree(file_buf);
+
+       return len;
+}
+
+static const struct file_operations tracing_saved_tgids_fops = {
+       .open   = tracing_open_generic,
+       .read   = tracing_saved_tgids_read,
+       .llseek = generic_file_llseek,
+};
+
 static ssize_t
 tracing_set_trace_read(struct file *filp, char __user *ubuf,
                       size_t cnt, loff_t *ppos)
@@ -4554,6 +4637,8 @@ out:
        return ret;
 }
 
+#ifdef CONFIG_TRACER_MAX_TRACE
+
 static ssize_t
 tracing_max_lat_read(struct file *filp, char __user *ubuf,
                     size_t cnt, loff_t *ppos)
@@ -4568,6 +4653,8 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf,
        return tracing_nsecs_write(filp->private_data, ubuf, cnt, ppos);
 }
 
+#endif
+
 static int tracing_open_pipe(struct inode *inode, struct file *filp)
 {
        struct trace_array *tr = inode->i_private;
@@ -4951,7 +5038,10 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
 
        spd.nr_pages = i;
 
-       ret = splice_to_pipe(pipe, &spd);
+       if (i)
+               ret = splice_to_pipe(pipe, &spd);
+       else
+               ret = 0;
 out:
        splice_shrink_spd(&spd);
        return ret;
@@ -5469,12 +5559,14 @@ static const struct file_operations tracing_thresh_fops = {
        .llseek         = generic_file_llseek,
 };
 
+#ifdef CONFIG_TRACER_MAX_TRACE
 static const struct file_operations tracing_max_lat_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_max_lat_read,
        .write          = tracing_max_lat_write,
        .llseek         = generic_file_llseek,
 };
+#endif
 
 static const struct file_operations set_tracer_fops = {
        .open           = tracing_open_generic,
@@ -6784,6 +6876,9 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
        trace_create_file("trace_marker", 0220, d_tracer,
                          tr, &tracing_mark_fops);
 
+       trace_create_file("saved_tgids", 0444, d_tracer,
+                         tr, &tracing_saved_tgids_fops);
+
        trace_create_file("trace_clock", 0644, d_tracer, tr,
                          &trace_clock_fops);
 
@@ -6847,7 +6942,9 @@ struct dentry *tracing_init_dentry(void)
        if (tr->dir)
                return NULL;
 
-       if (WARN_ON(!debugfs_initialized()))
+       if (WARN_ON(!tracefs_initialized()) ||
+               (IS_ENABLED(CONFIG_DEBUG_FS) &&
+                WARN_ON(!debugfs_initialized())))
                return ERR_PTR(-ENODEV);
 
        /*