aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2014-12-15 20:13:31 -0500
committerSteven Rostedt <rostedt@goodmis.org>2014-12-22 15:39:40 -0500
commitcf6ab6d9143b157786bf29bca5c32e55234bb07d (patch)
treea0c044f2bc377065ba823d08fbb33cb212c0148b /kernel/trace/trace.c
parent97bf6af1f928216fd6c5a66e8a57bfa95a659672 (diff)
tracing: Add ref count to tracer for when they are being read by pipe
When one of the trace pipe files are being read (by either the trace_pipe or trace_pipe_raw), do not allow the current_trace to change. By adding a ref count that is incremented when the pipe files are opened, will prevent the current_trace from being changed. This will allow for the removal of the global trace_types_lock from reading the pipe buffers (which is currently a bottle neck). Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2e767972e99c..ed3fba1d6570 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4140,6 +4140,12 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf)
4140 goto out; 4140 goto out;
4141 } 4141 }
4142 4142
4143 /* If trace pipe files are being read, we can't change the tracer */
4144 if (tr->current_trace->ref) {
4145 ret = -EBUSY;
4146 goto out;
4147 }
4148
4143 trace_branch_disable(); 4149 trace_branch_disable();
4144 4150
4145 tr->current_trace->enabled--; 4151 tr->current_trace->enabled--;
@@ -4363,6 +4369,8 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
4363 iter->trace->pipe_open(iter); 4369 iter->trace->pipe_open(iter);
4364 4370
4365 nonseekable_open(inode, filp); 4371 nonseekable_open(inode, filp);
4372
4373 tr->current_trace->ref++;
4366out: 4374out:
4367 mutex_unlock(&trace_types_lock); 4375 mutex_unlock(&trace_types_lock);
4368 return ret; 4376 return ret;
@@ -4382,6 +4390,8 @@ static int tracing_release_pipe(struct inode *inode, struct file *file)
4382 4390
4383 mutex_lock(&trace_types_lock); 4391 mutex_lock(&trace_types_lock);
4384 4392
4393 tr->current_trace->ref--;
4394
4385 if (iter->trace->pipe_close) 4395 if (iter->trace->pipe_close)
4386 iter->trace->pipe_close(iter); 4396 iter->trace->pipe_close(iter);
4387 4397
@@ -5331,6 +5341,8 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
5331 5341
5332 filp->private_data = info; 5342 filp->private_data = info;
5333 5343
5344 tr->current_trace->ref++;
5345
5334 mutex_unlock(&trace_types_lock); 5346 mutex_unlock(&trace_types_lock);
5335 5347
5336 ret = nonseekable_open(inode, filp); 5348 ret = nonseekable_open(inode, filp);
@@ -5437,6 +5449,8 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
5437 5449
5438 mutex_lock(&trace_types_lock); 5450 mutex_lock(&trace_types_lock);
5439 5451
5452 iter->tr->current_trace->ref--;
5453
5440 __trace_array_put(iter->tr); 5454 __trace_array_put(iter->tr);
5441 5455
5442 if (info->spare) 5456 if (info->spare)
@@ -6416,7 +6430,7 @@ static int instance_delete(const char *name)
6416 goto out_unlock; 6430 goto out_unlock;
6417 6431
6418 ret = -EBUSY; 6432 ret = -EBUSY;
6419 if (tr->ref) 6433 if (tr->ref || (tr->current_trace && tr->current_trace->ref))
6420 goto out_unlock; 6434 goto out_unlock;
6421 6435
6422 list_del(&tr->list); 6436 list_del(&tr->list);