aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2013-11-06 22:42:48 -0500
committerSteven Rostedt <rostedt@goodmis.org>2014-02-20 12:13:10 -0500
commit607e2ea167e56db84387f3ab97e59a862e101cab (patch)
treefc464e41f7a6f26aa04684bd1f92ea5182b52646 /kernel/trace
parentbf6065b5c7014ab30383405718c7a6b96d2cbdb2 (diff)
tracing: Set up infrastructure to allow tracers for instances
Currently the tracers (function, function_graph, irqsoff, etc) can only be used by the top level tracing directory (not for instances). This sets up the infrastructure to allow instances to be able to run a separate tracer apart from the what the top level tracing is doing. As tracers need to adapt for being used by instances, the tracers must flag if they can be used by instances or not. Currently only the 'nop' tracer can be used by all instances. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace.c72
-rw-r--r--kernel/trace/trace.h1
-rw-r--r--kernel/trace/trace_nop.c3
3 files changed, 60 insertions, 16 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);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 36e44732c650..ea51bb2004d2 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -364,6 +364,7 @@ struct tracer {
364 struct tracer_flags *flags; 364 struct tracer_flags *flags;
365 bool print_max; 365 bool print_max;
366 bool enabled; 366 bool enabled;
367 bool allow_instances;
367#ifdef CONFIG_TRACER_MAX_TRACE 368#ifdef CONFIG_TRACER_MAX_TRACE
368 bool use_max_tr; 369 bool use_max_tr;
369#endif 370#endif
diff --git a/kernel/trace/trace_nop.c b/kernel/trace/trace_nop.c
index f3984098c0d7..69a5cc94c01a 100644
--- a/kernel/trace/trace_nop.c
+++ b/kernel/trace/trace_nop.c
@@ -96,6 +96,7 @@ struct tracer nop_trace __read_mostly =
96 .selftest = trace_selftest_startup_nop, 96 .selftest = trace_selftest_startup_nop,
97#endif 97#endif
98 .flags = &nop_flags, 98 .flags = &nop_flags,
99 .set_flag = nop_set_flag 99 .set_flag = nop_set_flag,
100 .allow_instances = true,
100}; 101};
101 102