tracing: Fix regression of trace_pipe
[platform/kernel/linux-rpi.git] / kernel / trace / trace.c
index 61e081b..3c13e46 100644 (file)
@@ -2899,6 +2899,8 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
        if (copy_from_user(&buf, ubuf, cnt))
                return -EFAULT;
 
+       buf[cnt] = 0;
+
        trace_set_options(buf);
 
        *ppos += cnt;
@@ -3034,6 +3036,31 @@ static void set_buffer_entries(struct trace_array *tr, unsigned long val)
                tr->data[cpu]->entries = val;
 }
 
+/* resize @tr's buffer to the size of @size_tr's entries */
+static int resize_buffer_duplicate_size(struct trace_array *tr,
+                                       struct trace_array *size_tr, int cpu_id)
+{
+       int cpu, ret = 0;
+
+       if (cpu_id == RING_BUFFER_ALL_CPUS) {
+               for_each_tracing_cpu(cpu) {
+                       ret = ring_buffer_resize(tr->buffer,
+                                       size_tr->data[cpu]->entries, cpu);
+                       if (ret < 0)
+                               break;
+                       tr->data[cpu]->entries = size_tr->data[cpu]->entries;
+               }
+       } else {
+               ret = ring_buffer_resize(tr->buffer,
+                                       size_tr->data[cpu_id]->entries, cpu_id);
+               if (ret == 0)
+                       tr->data[cpu_id]->entries =
+                               size_tr->data[cpu_id]->entries;
+       }
+
+       return ret;
+}
+
 static int __tracing_resize_ring_buffer(unsigned long size, int cpu)
 {
        int ret;
@@ -3058,23 +3085,8 @@ static int __tracing_resize_ring_buffer(unsigned long size, int cpu)
 
        ret = ring_buffer_resize(max_tr.buffer, size, cpu);
        if (ret < 0) {
-               int r = 0;
-
-               if (cpu == RING_BUFFER_ALL_CPUS) {
-                       int i;
-                       for_each_tracing_cpu(i) {
-                               r = ring_buffer_resize(global_trace.buffer,
-                                               global_trace.data[i]->entries,
-                                               i);
-                               if (r < 0)
-                                       break;
-                       }
-               } else {
-                       r = ring_buffer_resize(global_trace.buffer,
-                                               global_trace.data[cpu]->entries,
-                                               cpu);
-               }
-
+               int r = resize_buffer_duplicate_size(&global_trace,
+                                                    &global_trace, cpu);
                if (r < 0) {
                        /*
                         * AARGH! We are left with different
@@ -3212,17 +3224,11 @@ static int tracing_set_tracer(const char *buf)
 
        topts = create_trace_option_files(t);
        if (t->use_max_tr) {
-               int cpu;
                /* we need to make per cpu buffer sizes equivalent */
-               for_each_tracing_cpu(cpu) {
-                       ret = ring_buffer_resize(max_tr.buffer,
-                                               global_trace.data[cpu]->entries,
-                                               cpu);
-                       if (ret < 0)
-                               goto out;
-                       max_tr.data[cpu]->entries =
-                                       global_trace.data[cpu]->entries;
-               }
+               ret = resize_buffer_duplicate_size(&max_tr, &global_trace,
+                                                  RING_BUFFER_ALL_CPUS);
+               if (ret < 0)
+                       goto out;
        }
 
        if (t->init) {
@@ -3448,7 +3454,7 @@ static int tracing_wait_pipe(struct file *filp)
                        return -EINTR;
 
                /*
-                * We block until we read something and tracing is enabled.
+                * We block until we read something and tracing is disabled.
                 * We still block if tracing is disabled, but we have never
                 * read anything. This allows a user to cat this file, and
                 * then enable tracing. But after we have read something,
@@ -3456,7 +3462,7 @@ static int tracing_wait_pipe(struct file *filp)
                 *
                 * iter->pos will be 0 if we haven't read anything.
                 */
-               if (tracing_is_enabled() && iter->pos)
+               if (!tracing_is_enabled() && iter->pos)
                        break;
        }
 
@@ -4271,13 +4277,11 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
                return -ENOMEM;
 
        if (*ppos & (PAGE_SIZE - 1)) {
-               WARN_ONCE(1, "Ftrace: previous read must page-align\n");
                ret = -EINVAL;
                goto out;
        }
 
        if (len & (PAGE_SIZE - 1)) {
-               WARN_ONCE(1, "Ftrace: splice_read should page-align\n");
                if (len < PAGE_SIZE) {
                        ret = -EINVAL;
                        goto out;
@@ -4813,10 +4817,17 @@ rb_simple_write(struct file *filp, const char __user *ubuf,
                return ret;
 
        if (buffer) {
-               if (val)
+               mutex_lock(&trace_types_lock);
+               if (val) {
                        ring_buffer_record_on(buffer);
-               else
+                       if (current_trace->start)
+                               current_trace->start(tr);
+               } else {
                        ring_buffer_record_off(buffer);
+                       if (current_trace->stop)
+                               current_trace->stop(tr);
+               }
+               mutex_unlock(&trace_types_lock);
        }
 
        (*ppos)++;