Skip to content

Commit

Permalink
tracing: Miscellaneous fixes for trace_array ref counting
Browse files Browse the repository at this point in the history
Some error paths did not handle ref counting properly, and some trace files need
ref counting.

Link: http://lkml.kernel.org/r/1374171524-11948-1-git-send-email-azl@google.com

Cc: stable@vger.kernel.org # 3.10
Cc: Vaibhav Nagarnaik <vnagarnaik@google.com>
Cc: David Sharp <dhsharp@google.com>
Cc: Alexander Z Lam <lambchop468@gmail.com>
Signed-off-by: Alexander Z Lam <azl@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
  • Loading branch information
Alexander Z Lam authored and Steven Rostedt committed Jul 19, 2013
1 parent 609e85a commit f77d09a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
24 changes: 18 additions & 6 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -3008,7 +3008,6 @@ static int tracing_release(struct inode *inode, struct file *file)

iter = m->private;
tr = iter->tr;
trace_array_put(tr);

mutex_lock(&trace_types_lock);

Expand All @@ -3023,6 +3022,9 @@ static int tracing_release(struct inode *inode, struct file *file)
if (!iter->snapshot)
/* reenable tracing if it was previously enabled */
tracing_start_tr(tr);

__trace_array_put(tr);

mutex_unlock(&trace_types_lock);

mutex_destroy(&iter->mutex);
Expand Down Expand Up @@ -3447,14 +3449,19 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
static int tracing_trace_options_open(struct inode *inode, struct file *file)
{
struct trace_array *tr = inode->i_private;
int ret;

if (tracing_disabled)
return -ENODEV;

if (trace_array_get(tr) < 0)
return -ENODEV;

return single_open(file, tracing_trace_options_show, inode->i_private);
ret = single_open(file, tracing_trace_options_show, inode->i_private);
if (ret < 0)
trace_array_put(tr);

return ret;
}

static const struct file_operations tracing_iter_fops = {
Expand Down Expand Up @@ -3958,6 +3965,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
iter = kzalloc(sizeof(*iter), GFP_KERNEL);
if (!iter) {
ret = -ENOMEM;
__trace_array_put(tr);
goto out;
}

Expand Down Expand Up @@ -4704,21 +4712,24 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file)
ret = PTR_ERR(iter);
} else {
/* Writes still need the seq_file to hold the private data */
ret = -ENOMEM;
m = kzalloc(sizeof(*m), GFP_KERNEL);
if (!m)
return -ENOMEM;
goto out;
iter = kzalloc(sizeof(*iter), GFP_KERNEL);
if (!iter) {
kfree(m);
return -ENOMEM;
goto out;
}
ret = 0;

iter->tr = tr;
iter->trace_buffer = &tc->tr->max_buffer;
iter->cpu_file = tc->cpu;
m->private = iter;
file->private_data = m;
}

out:
if (ret < 0)
trace_array_put(tr);

Expand Down Expand Up @@ -5328,9 +5339,10 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
}

static const struct file_operations tracing_stats_fops = {
.open = tracing_open_generic,
.open = tracing_open_generic_tc,
.read = tracing_stats_read,
.llseek = generic_file_llseek,
.release = tracing_release_generic_tc,
};

#ifdef CONFIG_DYNAMIC_FTRACE
Expand Down
21 changes: 19 additions & 2 deletions kernel/trace/trace_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,7 @@ show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)

static int ftrace_event_avail_open(struct inode *inode, struct file *file);
static int ftrace_event_set_open(struct inode *inode, struct file *file);
static int ftrace_event_release(struct inode *inode, struct file *file);

static const struct seq_operations show_event_seq_ops = {
.start = t_start,
Expand Down Expand Up @@ -1245,7 +1246,7 @@ static const struct file_operations ftrace_set_event_fops = {
.read = seq_read,
.write = ftrace_event_write,
.llseek = seq_lseek,
.release = seq_release,
.release = ftrace_event_release,
};

static const struct file_operations ftrace_enable_fops = {
Expand Down Expand Up @@ -1323,6 +1324,15 @@ ftrace_event_open(struct inode *inode, struct file *file,
return ret;
}

static int ftrace_event_release(struct inode *inode, struct file *file)
{
struct trace_array *tr = inode->i_private;

trace_array_put(tr);

return seq_release(inode, file);
}

static int
ftrace_event_avail_open(struct inode *inode, struct file *file)
{
Expand All @@ -1336,12 +1346,19 @@ ftrace_event_set_open(struct inode *inode, struct file *file)
{
const struct seq_operations *seq_ops = &show_set_event_seq_ops;
struct trace_array *tr = inode->i_private;
int ret;

if (trace_array_get(tr) < 0)
return -ENODEV;

if ((file->f_mode & FMODE_WRITE) &&
(file->f_flags & O_TRUNC))
ftrace_clear_events(tr);

return ftrace_event_open(inode, file, seq_ops);
ret = ftrace_event_open(inode, file, seq_ops);
if (ret < 0)
trace_array_put(tr);
return ret;
}

static struct event_subsystem *
Expand Down

0 comments on commit f77d09a

Please sign in to comment.