aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-07-23 11:26:06 -0400
committerSteven Rostedt <rostedt@rostedt.homelinux.com>2013-07-24 11:22:52 -0400
commit0bc392ee46d0fd8e6b678457ef71f074f19a03c5 (patch)
treee0f516c200ab6f1eea2f31323c6e4d24000d7e93 /kernel/trace/trace.c
parent4d3435b8a4c3357695e09c5e7a3bf73a19fca5b0 (diff)
tracing: Change tracing_entries_fops to rely on tracing_get_cpu()
tracing_open_generic_tc() is racy, the memory inode->i_private points to can be already freed. 1. Change its last user, tracing_entries_fops, to use tracing_*_generic_tr() instead. 2. Change debugfs_create_file("buffer_size_kb", data) callers to pass "data = tr". 3. Change tracing_entries_read() and tracing_entries_write() to use tracing_get_cpu(). 4. Kill the no longer used tracing_open_generic_tc() and tracing_release_generic_tc(). Link: http://lkml.kernel.org/r/20130723152606.GA23730@redhat.com Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c49
1 files changed, 12 insertions, 37 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e29dc8f69aac..68b46851666f 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2984,23 +2984,6 @@ static int tracing_open_generic_tr(struct inode *inode, struct file *filp)
2984 return 0; 2984 return 0;
2985} 2985}
2986 2986
2987static int tracing_open_generic_tc(struct inode *inode, struct file *filp)
2988{
2989 struct trace_cpu *tc = inode->i_private;
2990 struct trace_array *tr = tc->tr;
2991
2992 if (tracing_disabled)
2993 return -ENODEV;
2994
2995 if (trace_array_get(tr) < 0)
2996 return -ENODEV;
2997
2998 filp->private_data = inode->i_private;
2999
3000 return 0;
3001
3002}
3003
3004static int tracing_release(struct inode *inode, struct file *file) 2987static int tracing_release(struct inode *inode, struct file *file)
3005{ 2988{
3006 struct seq_file *m = file->private_data; 2989 struct seq_file *m = file->private_data;
@@ -3054,15 +3037,6 @@ static int tracing_release_generic_tr(struct inode *inode, struct file *file)
3054 return 0; 3037 return 0;
3055} 3038}
3056 3039
3057static int tracing_release_generic_tc(struct inode *inode, struct file *file)
3058{
3059 struct trace_cpu *tc = inode->i_private;
3060 struct trace_array *tr = tc->tr;
3061
3062 trace_array_put(tr);
3063 return 0;
3064}
3065
3066static int tracing_single_release_tr(struct inode *inode, struct file *file) 3040static int tracing_single_release_tr(struct inode *inode, struct file *file)
3067{ 3041{
3068 struct trace_array *tr = inode->i_private; 3042 struct trace_array *tr = inode->i_private;
@@ -4382,15 +4356,16 @@ static ssize_t
4382tracing_entries_read(struct file *filp, char __user *ubuf, 4356tracing_entries_read(struct file *filp, char __user *ubuf,
4383 size_t cnt, loff_t *ppos) 4357 size_t cnt, loff_t *ppos)
4384{ 4358{
4385 struct trace_cpu *tc = filp->private_data; 4359 struct inode *inode = file_inode(filp);
4386 struct trace_array *tr = tc->tr; 4360 struct trace_array *tr = inode->i_private;
4361 int cpu = tracing_get_cpu(inode);
4387 char buf[64]; 4362 char buf[64];
4388 int r = 0; 4363 int r = 0;
4389 ssize_t ret; 4364 ssize_t ret;
4390 4365
4391 mutex_lock(&trace_types_lock); 4366 mutex_lock(&trace_types_lock);
4392 4367
4393 if (tc->cpu == RING_BUFFER_ALL_CPUS) { 4368 if (cpu == RING_BUFFER_ALL_CPUS) {
4394 int cpu, buf_size_same; 4369 int cpu, buf_size_same;
4395 unsigned long size; 4370 unsigned long size;
4396 4371
@@ -4417,7 +4392,7 @@ tracing_entries_read(struct file *filp, char __user *ubuf,
4417 } else 4392 } else
4418 r = sprintf(buf, "X\n"); 4393 r = sprintf(buf, "X\n");
4419 } else 4394 } else
4420 r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, tc->cpu)->entries >> 10); 4395 r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10);
4421 4396
4422 mutex_unlock(&trace_types_lock); 4397 mutex_unlock(&trace_types_lock);
4423 4398
@@ -4429,7 +4404,8 @@ static ssize_t
4429tracing_entries_write(struct file *filp, const char __user *ubuf, 4404tracing_entries_write(struct file *filp, const char __user *ubuf,
4430 size_t cnt, loff_t *ppos) 4405 size_t cnt, loff_t *ppos)
4431{ 4406{
4432 struct trace_cpu *tc = filp->private_data; 4407 struct inode *inode = file_inode(filp);
4408 struct trace_array *tr = inode->i_private;
4433 unsigned long val; 4409 unsigned long val;
4434 int ret; 4410 int ret;
4435 4411
@@ -4443,8 +4419,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
4443 4419
4444 /* value is in KB */ 4420 /* value is in KB */
4445 val <<= 10; 4421 val <<= 10;
4446 4422 ret = tracing_resize_ring_buffer(tr, val, tracing_get_cpu(inode));
4447 ret = tracing_resize_ring_buffer(tc->tr, val, tc->cpu);
4448 if (ret < 0) 4423 if (ret < 0)
4449 return ret; 4424 return ret;
4450 4425
@@ -4892,11 +4867,11 @@ static const struct file_operations tracing_pipe_fops = {
4892}; 4867};
4893 4868
4894static const struct file_operations tracing_entries_fops = { 4869static const struct file_operations tracing_entries_fops = {
4895 .open = tracing_open_generic_tc, 4870 .open = tracing_open_generic_tr,
4896 .read = tracing_entries_read, 4871 .read = tracing_entries_read,
4897 .write = tracing_entries_write, 4872 .write = tracing_entries_write,
4898 .llseek = generic_file_llseek, 4873 .llseek = generic_file_llseek,
4899 .release = tracing_release_generic_tc, 4874 .release = tracing_release_generic_tr,
4900}; 4875};
4901 4876
4902static const struct file_operations tracing_total_entries_fops = { 4877static const struct file_operations tracing_total_entries_fops = {
@@ -5580,7 +5555,7 @@ tracing_init_debugfs_percpu(struct trace_array *tr, long cpu)
5580 tr, cpu, &tracing_stats_fops); 5555 tr, cpu, &tracing_stats_fops);
5581 5556
5582 trace_create_cpu_file("buffer_size_kb", 0444, d_cpu, 5557 trace_create_cpu_file("buffer_size_kb", 0444, d_cpu,
5583 &data->trace_cpu, cpu, &tracing_entries_fops); 5558 tr, cpu, &tracing_entries_fops);
5584 5559
5585#ifdef CONFIG_TRACER_SNAPSHOT 5560#ifdef CONFIG_TRACER_SNAPSHOT
5586 trace_create_cpu_file("snapshot", 0644, d_cpu, 5561 trace_create_cpu_file("snapshot", 0644, d_cpu,
@@ -6156,7 +6131,7 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer)
6156 tr, &tracing_pipe_fops); 6131 tr, &tracing_pipe_fops);
6157 6132
6158 trace_create_file("buffer_size_kb", 0644, d_tracer, 6133 trace_create_file("buffer_size_kb", 0644, d_tracer,
6159 (void *)&tr->trace_cpu, &tracing_entries_fops); 6134 tr, &tracing_entries_fops);
6160 6135
6161 trace_create_file("buffer_total_size_kb", 0444, d_tracer, 6136 trace_create_file("buffer_total_size_kb", 0444, d_tracer,
6162 tr, &tracing_total_entries_fops); 6137 tr, &tracing_total_entries_fops);