From: "Steven Rostedt (Red Hat)" <srost...@redhat.com>

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

Signed-off-by: Steven Rostedt <rost...@goodmis.org>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to