aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <srostedt@redhat.com>2013-03-06 15:27:24 -0500
committerSteven Rostedt <rostedt@goodmis.org>2013-03-15 00:35:51 -0400
commita695cb5816228f86576f5f5c6809fdf8ed382ece (patch)
tree922f12a1a2fab1efa16f74216d6883deeefd1b74 /kernel/trace/trace.c
parent121aaee7b0a82605d33af200c7e9ebab6fd6e444 (diff)
tracing: Prevent deleting instances when they are being read
Add a ref count to the trace_array structure and prevent removal of instances that have open descriptors. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index c547ebbe36ff..3a89496dc99b 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2613,6 +2613,8 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
2613 tracing_iter_reset(iter, cpu); 2613 tracing_iter_reset(iter, cpu);
2614 } 2614 }
2615 2615
2616 tr->ref++;
2617
2616 mutex_unlock(&trace_types_lock); 2618 mutex_unlock(&trace_types_lock);
2617 2619
2618 return iter; 2620 return iter;
@@ -2649,6 +2651,10 @@ static int tracing_release(struct inode *inode, struct file *file)
2649 tr = iter->tr; 2651 tr = iter->tr;
2650 2652
2651 mutex_lock(&trace_types_lock); 2653 mutex_lock(&trace_types_lock);
2654
2655 WARN_ON(!tr->ref);
2656 tr->ref--;
2657
2652 for_each_tracing_cpu(cpu) { 2658 for_each_tracing_cpu(cpu) {
2653 if (iter->buffer_iter[cpu]) 2659 if (iter->buffer_iter[cpu])
2654 ring_buffer_read_finish(iter->buffer_iter[cpu]); 2660 ring_buffer_read_finish(iter->buffer_iter[cpu]);
@@ -4460,6 +4466,10 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
4460 if (!info) 4466 if (!info)
4461 return -ENOMEM; 4467 return -ENOMEM;
4462 4468
4469 mutex_lock(&trace_types_lock);
4470
4471 tr->ref++;
4472
4463 info->iter.tr = tr; 4473 info->iter.tr = tr;
4464 info->iter.cpu_file = tc->cpu; 4474 info->iter.cpu_file = tc->cpu;
4465 info->iter.trace = tr->current_trace; 4475 info->iter.trace = tr->current_trace;
@@ -4470,6 +4480,8 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
4470 4480
4471 filp->private_data = info; 4481 filp->private_data = info;
4472 4482
4483 mutex_unlock(&trace_types_lock);
4484
4473 return nonseekable_open(inode, filp); 4485 return nonseekable_open(inode, filp);
4474} 4486}
4475 4487
@@ -4568,10 +4580,17 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
4568 struct ftrace_buffer_info *info = file->private_data; 4580 struct ftrace_buffer_info *info = file->private_data;
4569 struct trace_iterator *iter = &info->iter; 4581 struct trace_iterator *iter = &info->iter;
4570 4582
4583 mutex_lock(&trace_types_lock);
4584
4585 WARN_ON(!iter->tr->ref);
4586 iter->tr->ref--;
4587
4571 if (info->spare) 4588 if (info->spare)
4572 ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare); 4589 ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare);
4573 kfree(info); 4590 kfree(info);
4574 4591
4592 mutex_unlock(&trace_types_lock);
4593
4575 return 0; 4594 return 0;
4576} 4595}
4577 4596
@@ -5411,6 +5430,10 @@ static int instance_delete(const char *name)
5411 if (!found) 5430 if (!found)
5412 goto out_unlock; 5431 goto out_unlock;
5413 5432
5433 ret = -EBUSY;
5434 if (tr->ref)
5435 goto out_unlock;
5436
5414 list_del(&tr->list); 5437 list_del(&tr->list);
5415 5438
5416 event_trace_del_tracer(tr); 5439 event_trace_del_tracer(tr);