tracing: Move pipe reference to trace array instead of current_tracer
authorSteven Rostedt (VMware) <rostedt@goodmis.org>
Tue, 30 Jun 2020 03:45:56 +0000 (23:45 -0400)
committerSteven Rostedt (VMware) <rostedt@goodmis.org>
Tue, 30 Jun 2020 18:29:33 +0000 (14:29 -0400)
If a process has the trace_pipe open on a trace_array, the current tracer
for that trace array should not be changed. This was original enforced by a
global lock, but when instances were introduced, it was moved to the
current_trace. But this structure is shared by all instances, and a
trace_pipe is for a single instance. There's no reason that a process that
has trace_pipe open on one instance should prevent another instance from
changing its current tracer. Move the reference counter to the trace_array
instead.

This is marked as "Fixes" but is more of a clean up than a true fix.
Backport if you want, but its not critical.

Fixes: cf6ab6d9143b1 ("tracing: Add ref count to tracer for when they are being read by pipe")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
kernel/trace/trace.c
kernel/trace/trace.h

index 8241d1448d708d032faac094ba4a81b668afeca6..64c5b8146ccacb318ce3b871d454d53c72425162 100644 (file)
@@ -5891,7 +5891,7 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)
        }
 
        /* If trace pipe files are being read, we can't change the tracer */
-       if (tr->current_trace->ref) {
+       if (tr->trace_ref) {
                ret = -EBUSY;
                goto out;
        }
@@ -6107,7 +6107,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
 
        nonseekable_open(inode, filp);
 
-       tr->current_trace->ref++;
+       tr->trace_ref++;
 out:
        mutex_unlock(&trace_types_lock);
        return ret;
@@ -6126,7 +6126,7 @@ static int tracing_release_pipe(struct inode *inode, struct file *file)
 
        mutex_lock(&trace_types_lock);
 
-       tr->current_trace->ref--;
+       tr->trace_ref--;
 
        if (iter->trace->pipe_close)
                iter->trace->pipe_close(iter);
@@ -7428,7 +7428,7 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
 
        filp->private_data = info;
 
-       tr->current_trace->ref++;
+       tr->trace_ref++;
 
        mutex_unlock(&trace_types_lock);
 
@@ -7529,7 +7529,7 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
 
        mutex_lock(&trace_types_lock);
 
-       iter->tr->current_trace->ref--;
+       iter->tr->trace_ref--;
 
        __trace_array_put(iter->tr);
 
@@ -8737,7 +8737,7 @@ static int __remove_instance(struct trace_array *tr)
        int i;
 
        /* Reference counter for a newly created trace array = 1. */
-       if (tr->ref > 1 || (tr->current_trace && tr->current_trace->ref))
+       if (tr->ref > 1 || (tr->current_trace && tr->trace_ref))
                return -EBUSY;
 
        list_del(&tr->list);
index 13db4000af3fe20906737364a8be78d71e797bbd..f21607f8718912cb99d130e99150d5da3df5fd87 100644 (file)
@@ -356,6 +356,7 @@ struct trace_array {
        struct trace_event_file *trace_marker_file;
        cpumask_var_t           tracing_cpumask; /* only trace on set CPUs */
        int                     ref;
+       int                     trace_ref;
 #ifdef CONFIG_FUNCTION_TRACER
        struct ftrace_ops       *ops;
        struct trace_pid_list   __rcu *function_pids;
@@ -547,7 +548,6 @@ struct tracer {
        struct tracer           *next;
        struct tracer_flags     *flags;
        int                     enabled;
-       int                     ref;
        bool                    print_max;
        bool                    allow_instances;
 #ifdef CONFIG_TRACER_MAX_TRACE