OSDN Git Service

Merge tag 'trace-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux...
[tomoyo/tomoyo-test1.git] / kernel / trace / trace.c
index bc96567..3e55375 100644 (file)
@@ -4190,8 +4190,15 @@ static void *s_start(struct seq_file *m, loff_t *pos)
        int cpu;
 
        mutex_lock(&trace_types_lock);
-       if (unlikely(tr->current_trace != iter->trace))
+       if (unlikely(tr->current_trace != iter->trace)) {
+               /* Close iter->trace before switching to the new current tracer */
+               if (iter->trace->close)
+                       iter->trace->close(iter);
                iter->trace = tr->current_trace;
+               /* Reopen the new current tracer */
+               if (iter->trace->open)
+                       iter->trace->open(iter);
+       }
        mutex_unlock(&trace_types_lock);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
@@ -5258,11 +5265,17 @@ int tracing_set_cpumask(struct trace_array *tr,
                                !cpumask_test_cpu(cpu, tracing_cpumask_new)) {
                        atomic_inc(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled);
                        ring_buffer_record_disable_cpu(tr->array_buffer.buffer, cpu);
+#ifdef CONFIG_TRACER_MAX_TRACE
+                       ring_buffer_record_disable_cpu(tr->max_buffer.buffer, cpu);
+#endif
                }
                if (!cpumask_test_cpu(cpu, tr->tracing_cpumask) &&
                                cpumask_test_cpu(cpu, tracing_cpumask_new)) {
                        atomic_dec(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled);
                        ring_buffer_record_enable_cpu(tr->array_buffer.buffer, cpu);
+#ifdef CONFIG_TRACER_MAX_TRACE
+                       ring_buffer_record_enable_cpu(tr->max_buffer.buffer, cpu);
+#endif
                }
        }
        arch_spin_unlock(&tr->max_lock);
@@ -6689,10 +6702,36 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf,
 
 #endif
 
+static int open_pipe_on_cpu(struct trace_array *tr, int cpu)
+{
+       if (cpu == RING_BUFFER_ALL_CPUS) {
+               if (cpumask_empty(tr->pipe_cpumask)) {
+                       cpumask_setall(tr->pipe_cpumask);
+                       return 0;
+               }
+       } else if (!cpumask_test_cpu(cpu, tr->pipe_cpumask)) {
+               cpumask_set_cpu(cpu, tr->pipe_cpumask);
+               return 0;
+       }
+       return -EBUSY;
+}
+
+static void close_pipe_on_cpu(struct trace_array *tr, int cpu)
+{
+       if (cpu == RING_BUFFER_ALL_CPUS) {
+               WARN_ON(!cpumask_full(tr->pipe_cpumask));
+               cpumask_clear(tr->pipe_cpumask);
+       } else {
+               WARN_ON(!cpumask_test_cpu(cpu, tr->pipe_cpumask));
+               cpumask_clear_cpu(cpu, tr->pipe_cpumask);
+       }
+}
+
 static int tracing_open_pipe(struct inode *inode, struct file *filp)
 {
        struct trace_array *tr = inode->i_private;
        struct trace_iterator *iter;
+       int cpu;
        int ret;
 
        ret = tracing_check_open_get_tr(tr);
@@ -6700,13 +6739,16 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
                return ret;
 
        mutex_lock(&trace_types_lock);
+       cpu = tracing_get_cpu(inode);
+       ret = open_pipe_on_cpu(tr, cpu);
+       if (ret)
+               goto fail_pipe_on_cpu;
 
        /* create a buffer to store the information to pass to userspace */
        iter = kzalloc(sizeof(*iter), GFP_KERNEL);
        if (!iter) {
                ret = -ENOMEM;
-               __trace_array_put(tr);
-               goto out;
+               goto fail_alloc_iter;
        }
 
        trace_seq_init(&iter->seq);
@@ -6729,7 +6771,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
 
        iter->tr = tr;
        iter->array_buffer = &tr->array_buffer;
-       iter->cpu_file = tracing_get_cpu(inode);
+       iter->cpu_file = cpu;
        mutex_init(&iter->mutex);
        filp->private_data = iter;
 
@@ -6739,12 +6781,15 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
        nonseekable_open(inode, filp);
 
        tr->trace_ref++;
-out:
+
        mutex_unlock(&trace_types_lock);
        return ret;
 
 fail:
        kfree(iter);
+fail_alloc_iter:
+       close_pipe_on_cpu(tr, cpu);
+fail_pipe_on_cpu:
        __trace_array_put(tr);
        mutex_unlock(&trace_types_lock);
        return ret;
@@ -6761,7 +6806,7 @@ static int tracing_release_pipe(struct inode *inode, struct file *file)
 
        if (iter->trace->pipe_close)
                iter->trace->pipe_close(iter);
-
+       close_pipe_on_cpu(tr, iter->cpu_file);
        mutex_unlock(&trace_types_lock);
 
        free_trace_iter_content(iter);
@@ -9422,6 +9467,9 @@ static struct trace_array *trace_array_create(const char *name)
        if (!alloc_cpumask_var(&tr->tracing_cpumask, GFP_KERNEL))
                goto out_free_tr;
 
+       if (!alloc_cpumask_var(&tr->pipe_cpumask, GFP_KERNEL))
+               goto out_free_tr;
+
        tr->trace_flags = global_trace.trace_flags & ~ZEROED_TRACE_FLAGS;
 
        cpumask_copy(tr->tracing_cpumask, cpu_all_mask);
@@ -9463,6 +9511,7 @@ static struct trace_array *trace_array_create(const char *name)
  out_free_tr:
        ftrace_free_ftrace_ops(tr);
        free_trace_buffers(tr);
+       free_cpumask_var(tr->pipe_cpumask);
        free_cpumask_var(tr->tracing_cpumask);
        kfree(tr->name);
        kfree(tr);
@@ -9565,6 +9614,7 @@ static int __remove_instance(struct trace_array *tr)
        }
        kfree(tr->topts);
 
+       free_cpumask_var(tr->pipe_cpumask);
        free_cpumask_var(tr->tracing_cpumask);
        kfree(tr->name);
        kfree(tr);
@@ -10362,12 +10412,14 @@ __init static int tracer_alloc_buffers(void)
        if (trace_create_savedcmd() < 0)
                goto out_free_temp_buffer;
 
+       if (!alloc_cpumask_var(&global_trace.pipe_cpumask, GFP_KERNEL))
+               goto out_free_savedcmd;
+
        /* TODO: make the number of buffers hot pluggable with CPUS */
        if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) {
                MEM_FAIL(1, "tracer: failed to allocate ring buffer!\n");
-               goto out_free_savedcmd;
+               goto out_free_pipe_cpumask;
        }
-
        if (global_trace.buffer_disabled)
                tracing_off();
 
@@ -10420,6 +10472,8 @@ __init static int tracer_alloc_buffers(void)
 
        return 0;
 
+out_free_pipe_cpumask:
+       free_cpumask_var(global_trace.pipe_cpumask);
 out_free_savedcmd:
        free_saved_cmdlines_buffer(savedcmd);
 out_free_temp_buffer: