aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace.c83
1 files changed, 65 insertions, 18 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e36da7ff59bf..6be9df1aa513 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -204,6 +204,37 @@ static struct trace_array global_trace;
204 204
205LIST_HEAD(ftrace_trace_arrays); 205LIST_HEAD(ftrace_trace_arrays);
206 206
207int trace_array_get(struct trace_array *this_tr)
208{
209 struct trace_array *tr;
210 int ret = -ENODEV;
211
212 mutex_lock(&trace_types_lock);
213 list_for_each_entry(tr, &ftrace_trace_arrays, list) {
214 if (tr == this_tr) {
215 tr->ref++;
216 ret = 0;
217 break;
218 }
219 }
220 mutex_unlock(&trace_types_lock);
221
222 return ret;
223}
224
225static void __trace_array_put(struct trace_array *this_tr)
226{
227 WARN_ON(!this_tr->ref);
228 this_tr->ref--;
229}
230
231void trace_array_put(struct trace_array *this_tr)
232{
233 mutex_lock(&trace_types_lock);
234 __trace_array_put(this_tr);
235 mutex_unlock(&trace_types_lock);
236}
237
207int filter_current_check_discard(struct ring_buffer *buffer, 238int filter_current_check_discard(struct ring_buffer *buffer,
208 struct ftrace_event_call *call, void *rec, 239 struct ftrace_event_call *call, void *rec,
209 struct ring_buffer_event *event) 240 struct ring_buffer_event *event)
@@ -2831,10 +2862,9 @@ static const struct seq_operations tracer_seq_ops = {
2831}; 2862};
2832 2863
2833static struct trace_iterator * 2864static struct trace_iterator *
2834__tracing_open(struct inode *inode, struct file *file, bool snapshot) 2865__tracing_open(struct trace_array *tr, struct trace_cpu *tc,
2866 struct inode *inode, struct file *file, bool snapshot)
2835{ 2867{
2836 struct trace_cpu *tc = inode->i_private;
2837 struct trace_array *tr = tc->tr;
2838 struct trace_iterator *iter; 2868 struct trace_iterator *iter;
2839 int cpu; 2869 int cpu;
2840 2870
@@ -2913,8 +2943,6 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
2913 tracing_iter_reset(iter, cpu); 2943 tracing_iter_reset(iter, cpu);
2914 } 2944 }
2915 2945
2916 tr->ref++;
2917
2918 mutex_unlock(&trace_types_lock); 2946 mutex_unlock(&trace_types_lock);
2919 2947
2920 return iter; 2948 return iter;
@@ -2944,17 +2972,20 @@ static int tracing_release(struct inode *inode, struct file *file)
2944 struct trace_array *tr; 2972 struct trace_array *tr;
2945 int cpu; 2973 int cpu;
2946 2974
2947 if (!(file->f_mode & FMODE_READ)) 2975 /* Writes do not use seq_file, need to grab tr from inode */
2976 if (!(file->f_mode & FMODE_READ)) {
2977 struct trace_cpu *tc = inode->i_private;
2978
2979 trace_array_put(tc->tr);
2948 return 0; 2980 return 0;
2981 }
2949 2982
2950 iter = m->private; 2983 iter = m->private;
2951 tr = iter->tr; 2984 tr = iter->tr;
2985 trace_array_put(tr);
2952 2986
2953 mutex_lock(&trace_types_lock); 2987 mutex_lock(&trace_types_lock);
2954 2988
2955 WARN_ON(!tr->ref);
2956 tr->ref--;
2957
2958 for_each_tracing_cpu(cpu) { 2989 for_each_tracing_cpu(cpu) {
2959 if (iter->buffer_iter[cpu]) 2990 if (iter->buffer_iter[cpu])
2960 ring_buffer_read_finish(iter->buffer_iter[cpu]); 2991 ring_buffer_read_finish(iter->buffer_iter[cpu]);
@@ -2973,20 +3004,23 @@ static int tracing_release(struct inode *inode, struct file *file)
2973 kfree(iter->trace); 3004 kfree(iter->trace);
2974 kfree(iter->buffer_iter); 3005 kfree(iter->buffer_iter);
2975 seq_release_private(inode, file); 3006 seq_release_private(inode, file);
3007
2976 return 0; 3008 return 0;
2977} 3009}
2978 3010
2979static int tracing_open(struct inode *inode, struct file *file) 3011static int tracing_open(struct inode *inode, struct file *file)
2980{ 3012{
3013 struct trace_cpu *tc = inode->i_private;
3014 struct trace_array *tr = tc->tr;
2981 struct trace_iterator *iter; 3015 struct trace_iterator *iter;
2982 int ret = 0; 3016 int ret = 0;
2983 3017
3018 if (trace_array_get(tr) < 0)
3019 return -ENODEV;
3020
2984 /* If this file was open for write, then erase contents */ 3021 /* If this file was open for write, then erase contents */
2985 if ((file->f_mode & FMODE_WRITE) && 3022 if ((file->f_mode & FMODE_WRITE) &&
2986 (file->f_flags & O_TRUNC)) { 3023 (file->f_flags & O_TRUNC)) {
2987 struct trace_cpu *tc = inode->i_private;
2988 struct trace_array *tr = tc->tr;
2989
2990 if (tc->cpu == RING_BUFFER_ALL_CPUS) 3024 if (tc->cpu == RING_BUFFER_ALL_CPUS)
2991 tracing_reset_online_cpus(&tr->trace_buffer); 3025 tracing_reset_online_cpus(&tr->trace_buffer);
2992 else 3026 else
@@ -2994,12 +3028,16 @@ static int tracing_open(struct inode *inode, struct file *file)
2994 } 3028 }
2995 3029
2996 if (file->f_mode & FMODE_READ) { 3030 if (file->f_mode & FMODE_READ) {
2997 iter = __tracing_open(inode, file, false); 3031 iter = __tracing_open(tr, tc, inode, file, false);
2998 if (IS_ERR(iter)) 3032 if (IS_ERR(iter))
2999 ret = PTR_ERR(iter); 3033 ret = PTR_ERR(iter);
3000 else if (trace_flags & TRACE_ITER_LATENCY_FMT) 3034 else if (trace_flags & TRACE_ITER_LATENCY_FMT)
3001 iter->iter_flags |= TRACE_FILE_LAT_FMT; 3035 iter->iter_flags |= TRACE_FILE_LAT_FMT;
3002 } 3036 }
3037
3038 if (ret < 0)
3039 trace_array_put(tr);
3040
3003 return ret; 3041 return ret;
3004} 3042}
3005 3043
@@ -4575,12 +4613,16 @@ struct ftrace_buffer_info {
4575static int tracing_snapshot_open(struct inode *inode, struct file *file) 4613static int tracing_snapshot_open(struct inode *inode, struct file *file)
4576{ 4614{
4577 struct trace_cpu *tc = inode->i_private; 4615 struct trace_cpu *tc = inode->i_private;
4616 struct trace_array *tr = tc->tr;
4578 struct trace_iterator *iter; 4617 struct trace_iterator *iter;
4579 struct seq_file *m; 4618 struct seq_file *m;
4580 int ret = 0; 4619 int ret = 0;
4581 4620
4621 if (trace_array_get(tr) < 0)
4622 return -ENODEV;
4623
4582 if (file->f_mode & FMODE_READ) { 4624 if (file->f_mode & FMODE_READ) {
4583 iter = __tracing_open(inode, file, true); 4625 iter = __tracing_open(tr, tc, inode, file, true);
4584 if (IS_ERR(iter)) 4626 if (IS_ERR(iter))
4585 ret = PTR_ERR(iter); 4627 ret = PTR_ERR(iter);
4586 } else { 4628 } else {
@@ -4593,13 +4635,16 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file)
4593 kfree(m); 4635 kfree(m);
4594 return -ENOMEM; 4636 return -ENOMEM;
4595 } 4637 }
4596 iter->tr = tc->tr; 4638 iter->tr = tr;
4597 iter->trace_buffer = &tc->tr->max_buffer; 4639 iter->trace_buffer = &tc->tr->max_buffer;
4598 iter->cpu_file = tc->cpu; 4640 iter->cpu_file = tc->cpu;
4599 m->private = iter; 4641 m->private = iter;
4600 file->private_data = m; 4642 file->private_data = m;
4601 } 4643 }
4602 4644
4645 if (ret < 0)
4646 trace_array_put(tr);
4647
4603 return ret; 4648 return ret;
4604} 4649}
4605 4650
@@ -4680,9 +4725,12 @@ out:
4680static int tracing_snapshot_release(struct inode *inode, struct file *file) 4725static int tracing_snapshot_release(struct inode *inode, struct file *file)
4681{ 4726{
4682 struct seq_file *m = file->private_data; 4727 struct seq_file *m = file->private_data;
4728 int ret;
4729
4730 ret = tracing_release(inode, file);
4683 4731
4684 if (file->f_mode & FMODE_READ) 4732 if (file->f_mode & FMODE_READ)
4685 return tracing_release(inode, file); 4733 return ret;
4686 4734
4687 /* If write only, the seq_file is just a stub */ 4735 /* If write only, the seq_file is just a stub */
4688 if (m) 4736 if (m)
@@ -4927,8 +4975,7 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
4927 4975
4928 mutex_lock(&trace_types_lock); 4976 mutex_lock(&trace_types_lock);
4929 4977
4930 WARN_ON(!iter->tr->ref); 4978 __trace_array_put(iter->tr);
4931 iter->tr->ref--;
4932 4979
4933 if (info->spare) 4980 if (info->spare)
4934 ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare); 4981 ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare);