aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c72
1 files changed, 57 insertions, 15 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index ee8da93e91e0..944cd021aabf 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -119,7 +119,7 @@ enum ftrace_dump_mode ftrace_dump_on_oops;
119/* When set, tracing will stop when a WARN*() is hit */ 119/* When set, tracing will stop when a WARN*() is hit */
120int __disable_trace_on_warning; 120int __disable_trace_on_warning;
121 121
122static int tracing_set_tracer(const char *buf); 122static int tracing_set_tracer(struct trace_array *tr, const char *buf);
123 123
124#define MAX_TRACER_SIZE 100 124#define MAX_TRACER_SIZE 100
125static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata; 125static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata;
@@ -1231,7 +1231,7 @@ int register_tracer(struct tracer *type)
1231 1231
1232 printk(KERN_INFO "Starting tracer '%s'\n", type->name); 1232 printk(KERN_INFO "Starting tracer '%s'\n", type->name);
1233 /* Do we want this tracer to start on bootup? */ 1233 /* Do we want this tracer to start on bootup? */
1234 tracing_set_tracer(type->name); 1234 tracing_set_tracer(&global_trace, type->name);
1235 default_bootup_tracer = NULL; 1235 default_bootup_tracer = NULL;
1236 /* disable other selftests, since this will break it. */ 1236 /* disable other selftests, since this will break it. */
1237 tracing_selftest_disabled = true; 1237 tracing_selftest_disabled = true;
@@ -3122,27 +3122,52 @@ static int tracing_open(struct inode *inode, struct file *file)
3122 return ret; 3122 return ret;
3123} 3123}
3124 3124
3125/*
3126 * Some tracers are not suitable for instance buffers.
3127 * A tracer is always available for the global array (toplevel)
3128 * or if it explicitly states that it is.
3129 */
3130static bool
3131trace_ok_for_array(struct tracer *t, struct trace_array *tr)
3132{
3133 return (tr->flags & TRACE_ARRAY_FL_GLOBAL) || t->allow_instances;
3134}
3135
3136/* Find the next tracer that this trace array may use */
3137static struct tracer *
3138get_tracer_for_array(struct trace_array *tr, struct tracer *t)
3139{
3140 while (t && !trace_ok_for_array(t, tr))
3141 t = t->next;
3142
3143 return t;
3144}
3145
3125static void * 3146static void *
3126t_next(struct seq_file *m, void *v, loff_t *pos) 3147t_next(struct seq_file *m, void *v, loff_t *pos)
3127{ 3148{
3149 struct trace_array *tr = m->private;
3128 struct tracer *t = v; 3150 struct tracer *t = v;
3129 3151
3130 (*pos)++; 3152 (*pos)++;
3131 3153
3132 if (t) 3154 if (t)
3133 t = t->next; 3155 t = get_tracer_for_array(tr, t->next);
3134 3156
3135 return t; 3157 return t;
3136} 3158}
3137 3159
3138static void *t_start(struct seq_file *m, loff_t *pos) 3160static void *t_start(struct seq_file *m, loff_t *pos)
3139{ 3161{
3162 struct trace_array *tr = m->private;
3140 struct tracer *t; 3163 struct tracer *t;
3141 loff_t l = 0; 3164 loff_t l = 0;
3142 3165
3143 mutex_lock(&trace_types_lock); 3166 mutex_lock(&trace_types_lock);
3144 for (t = trace_types; t && l < *pos; t = t_next(m, t, &l)) 3167
3145 ; 3168 t = get_tracer_for_array(tr, trace_types);
3169 for (; t && l < *pos; t = t_next(m, t, &l))
3170 ;
3146 3171
3147 return t; 3172 return t;
3148} 3173}
@@ -3177,10 +3202,21 @@ static const struct seq_operations show_traces_seq_ops = {
3177 3202
3178static int show_traces_open(struct inode *inode, struct file *file) 3203static int show_traces_open(struct inode *inode, struct file *file)
3179{ 3204{
3205 struct trace_array *tr = inode->i_private;
3206 struct seq_file *m;
3207 int ret;
3208
3180 if (tracing_disabled) 3209 if (tracing_disabled)
3181 return -ENODEV; 3210 return -ENODEV;
3182 3211
3183 return seq_open(file, &show_traces_seq_ops); 3212 ret = seq_open(file, &show_traces_seq_ops);
3213 if (ret)
3214 return ret;
3215
3216 m = file->private_data;
3217 m->private = tr;
3218
3219 return 0;
3184} 3220}
3185 3221
3186static ssize_t 3222static ssize_t
@@ -3871,10 +3907,9 @@ create_trace_option_files(struct trace_array *tr, struct tracer *tracer);
3871static void 3907static void
3872destroy_trace_option_files(struct trace_option_dentry *topts); 3908destroy_trace_option_files(struct trace_option_dentry *topts);
3873 3909
3874static int tracing_set_tracer(const char *buf) 3910static int tracing_set_tracer(struct trace_array *tr, const char *buf)
3875{ 3911{
3876 static struct trace_option_dentry *topts; 3912 static struct trace_option_dentry *topts;
3877 struct trace_array *tr = &global_trace;
3878 struct tracer *t; 3913 struct tracer *t;
3879#ifdef CONFIG_TRACER_MAX_TRACE 3914#ifdef CONFIG_TRACER_MAX_TRACE
3880 bool had_max_tr; 3915 bool had_max_tr;
@@ -3902,6 +3937,12 @@ static int tracing_set_tracer(const char *buf)
3902 if (t == tr->current_trace) 3937 if (t == tr->current_trace)
3903 goto out; 3938 goto out;
3904 3939
3940 /* Some tracers are only allowed for the top level buffer */
3941 if (!trace_ok_for_array(t, tr)) {
3942 ret = -EINVAL;
3943 goto out;
3944 }
3945
3905 trace_branch_disable(); 3946 trace_branch_disable();
3906 3947
3907 tr->current_trace->enabled = false; 3948 tr->current_trace->enabled = false;
@@ -3958,6 +3999,7 @@ static ssize_t
3958tracing_set_trace_write(struct file *filp, const char __user *ubuf, 3999tracing_set_trace_write(struct file *filp, const char __user *ubuf,
3959 size_t cnt, loff_t *ppos) 4000 size_t cnt, loff_t *ppos)
3960{ 4001{
4002 struct trace_array *tr = filp->private_data;
3961 char buf[MAX_TRACER_SIZE+1]; 4003 char buf[MAX_TRACER_SIZE+1];
3962 int i; 4004 int i;
3963 size_t ret; 4005 size_t ret;
@@ -3977,7 +4019,7 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
3977 for (i = cnt - 1; i > 0 && isspace(buf[i]); i--) 4019 for (i = cnt - 1; i > 0 && isspace(buf[i]); i--)
3978 buf[i] = 0; 4020 buf[i] = 0;
3979 4021
3980 err = tracing_set_tracer(buf); 4022 err = tracing_set_tracer(tr, buf);
3981 if (err) 4023 if (err)
3982 return err; 4024 return err;
3983 4025
@@ -6193,6 +6235,12 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer)
6193{ 6235{
6194 int cpu; 6236 int cpu;
6195 6237
6238 trace_create_file("available_tracers", 0444, d_tracer,
6239 tr, &show_traces_fops);
6240
6241 trace_create_file("current_tracer", 0644, d_tracer,
6242 tr, &set_tracer_fops);
6243
6196 trace_create_file("tracing_cpumask", 0644, d_tracer, 6244 trace_create_file("tracing_cpumask", 0644, d_tracer,
6197 tr, &tracing_cpumask_fops); 6245 tr, &tracing_cpumask_fops);
6198 6246
@@ -6245,12 +6293,6 @@ static __init int tracer_init_debugfs(void)
6245 6293
6246 init_tracer_debugfs(&global_trace, d_tracer); 6294 init_tracer_debugfs(&global_trace, d_tracer);
6247 6295
6248 trace_create_file("available_tracers", 0444, d_tracer,
6249 &global_trace, &show_traces_fops);
6250
6251 trace_create_file("current_tracer", 0644, d_tracer,
6252 &global_trace, &set_tracer_fops);
6253
6254#ifdef CONFIG_TRACER_MAX_TRACE 6296#ifdef CONFIG_TRACER_MAX_TRACE
6255 trace_create_file("tracing_max_latency", 0644, d_tracer, 6297 trace_create_file("tracing_max_latency", 0644, d_tracer,
6256 &tracing_max_latency, &tracing_max_lat_fops); 6298 &tracing_max_latency, &tracing_max_lat_fops);