[for-next][PATCH 14/17] tracing: Prevent deleting instances when they are being read

From: Steven Rostedt
Date: Thu Mar 07 2013 - 22:11:01 EST


From: "Steven Rostedt (Red Hat)" <srostedt@xxxxxxxxxx>

Add a ref count to the trace_array structure and prevent removal
of instances that have open descriptors.

Signed-off-by: Steven Rostedt <rostedt@xxxxxxxxxxx>
---
kernel/trace/trace.c | 23 +++++++++++++++++++++++
kernel/trace/trace.h | 1 +
2 files changed, 24 insertions(+)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e6547ea..8ede7d1 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2612,6 +2612,8 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
tracing_iter_reset(iter, cpu);
}

+ tr->ref++;
+
mutex_unlock(&trace_types_lock);

return iter;
@@ -2648,6 +2650,10 @@ static int tracing_release(struct inode *inode, struct file *file)
tr = iter->tr;

mutex_lock(&trace_types_lock);
+
+ WARN_ON(!tr->ref);
+ tr->ref--;
+
for_each_tracing_cpu(cpu) {
if (iter->buffer_iter[cpu])
ring_buffer_read_finish(iter->buffer_iter[cpu]);
@@ -4431,6 +4437,10 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
if (!info)
return -ENOMEM;

+ mutex_lock(&trace_types_lock);
+
+ tr->ref++;
+
info->iter.tr = tr;
info->iter.cpu_file = tc->cpu;
info->iter.trace = tr->current_trace;
@@ -4441,6 +4451,8 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)

filp->private_data = info;

+ mutex_unlock(&trace_types_lock);
+
return nonseekable_open(inode, filp);
}

@@ -4539,10 +4551,17 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
struct ftrace_buffer_info *info = file->private_data;
struct trace_iterator *iter = &info->iter;

+ mutex_lock(&trace_types_lock);
+
+ WARN_ON(!iter->tr->ref);
+ iter->tr->ref--;
+
if (info->spare)
ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare);
kfree(info);

+ mutex_unlock(&trace_types_lock);
+
return 0;
}

@@ -5375,6 +5394,10 @@ static int instance_delete(const char *name)
if (!found)
goto out_unlock;

+ ret = -EBUSY;
+ if (tr->ref)
+ goto out_unlock;
+
list_del(&tr->list);

event_trace_del_tracer(tr);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 6111933..a19459d 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -219,6 +219,7 @@ struct trace_array {
struct list_head systems;
struct list_head events;
struct task_struct *waiter;
+ int ref;
};

enum {
--
1.7.10.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/