diff options
author | Steven Rostedt (Red Hat) <rostedt@goodmis.org> | 2014-12-15 20:13:31 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2014-12-22 15:39:40 -0500 |
commit | cf6ab6d9143b157786bf29bca5c32e55234bb07d (patch) | |
tree | a0c044f2bc377065ba823d08fbb33cb212c0148b /kernel/trace/trace.c | |
parent | 97bf6af1f928216fd6c5a66e8a57bfa95a659672 (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.c | 16 |
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++; | ||
4366 | out: | 4374 | out: |
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); |