aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2015-09-30 14:27:31 -0400
committerSteven Rostedt <rostedt@goodmis.org>2015-09-30 15:22:58 -0400
commit37aea98b84c0ce2ac638510fefeed9f8f920bd34 (patch)
tree296e763fd1dabf200f1dec9b70d1f226dd077243
parent16270145ce6b90750bbe4f9365865f65037b2027 (diff)
tracing: Add trace options for tracer options to instances
Add the tracer options to instances options directory as well. Only add the options for tracers that are allowed to be enabled by an instance. But note, that tracer options are global. That is, tracer options enabled in an instance, also take affect at the top level and in other instances. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--kernel/trace/trace.c80
-rw-r--r--kernel/trace/trace.h9
2 files changed, 67 insertions, 22 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 7b99e36b8973..78022c1a125f 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4308,7 +4308,7 @@ int tracing_update_buffers(void)
4308 4308
4309struct trace_option_dentry; 4309struct trace_option_dentry;
4310 4310
4311static struct trace_option_dentry * 4311static void
4312create_trace_option_files(struct trace_array *tr, struct tracer *tracer); 4312create_trace_option_files(struct trace_array *tr, struct tracer *tracer);
4313 4313
4314/* 4314/*
@@ -4334,15 +4334,7 @@ static void add_tracer_options(struct trace_array *tr, struct tracer *t)
4334 if (!tr->dir) 4334 if (!tr->dir)
4335 return; 4335 return;
4336 4336
4337 /* Currently, only the top instance has options */ 4337 create_trace_option_files(tr, t);
4338 if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL))
4339 return;
4340
4341 /* Ignore if they were already created */
4342 if (t->topts)
4343 return;
4344
4345 t->topts = create_trace_option_files(tr, t);
4346} 4338}
4347 4339
4348static int tracing_set_tracer(struct trace_array *tr, const char *buf) 4340static int tracing_set_tracer(struct trace_array *tr, const char *buf)
@@ -6341,21 +6333,39 @@ create_trace_option_file(struct trace_array *tr,
6341 6333
6342} 6334}
6343 6335
6344static struct trace_option_dentry * 6336static void
6345create_trace_option_files(struct trace_array *tr, struct tracer *tracer) 6337create_trace_option_files(struct trace_array *tr, struct tracer *tracer)
6346{ 6338{
6347 struct trace_option_dentry *topts; 6339 struct trace_option_dentry *topts;
6340 struct trace_options *tr_topts;
6348 struct tracer_flags *flags; 6341 struct tracer_flags *flags;
6349 struct tracer_opt *opts; 6342 struct tracer_opt *opts;
6350 int cnt; 6343 int cnt;
6344 int i;
6351 6345
6352 if (!tracer) 6346 if (!tracer)
6353 return NULL; 6347 return;
6354 6348
6355 flags = tracer->flags; 6349 flags = tracer->flags;
6356 6350
6357 if (!flags || !flags->opts) 6351 if (!flags || !flags->opts)
6358 return NULL; 6352 return;
6353
6354 /*
6355 * If this is an instance, only create flags for tracers
6356 * the instance may have.
6357 */
6358 if (!trace_ok_for_array(tracer, tr))
6359 return;
6360
6361 for (i = 0; i < tr->nr_topts; i++) {
6362 /*
6363 * Check if these flags have already been added.
6364 * Some tracers share flags.
6365 */
6366 if (tr->topts[i].tracer->flags == tracer->flags)
6367 return;
6368 }
6359 6369
6360 opts = flags->opts; 6370 opts = flags->opts;
6361 6371
@@ -6364,7 +6374,19 @@ create_trace_option_files(struct trace_array *tr, struct tracer *tracer)
6364 6374
6365 topts = kcalloc(cnt + 1, sizeof(*topts), GFP_KERNEL); 6375 topts = kcalloc(cnt + 1, sizeof(*topts), GFP_KERNEL);
6366 if (!topts) 6376 if (!topts)
6367 return NULL; 6377 return;
6378
6379 tr_topts = krealloc(tr->topts, sizeof(*tr->topts) * (tr->nr_topts + 1),
6380 GFP_KERNEL);
6381 if (!tr_topts) {
6382 kfree(topts);
6383 return;
6384 }
6385
6386 tr->topts = tr_topts;
6387 tr->topts[tr->nr_topts].tracer = tracer;
6388 tr->topts[tr->nr_topts].topts = topts;
6389 tr->nr_topts++;
6368 6390
6369 for (cnt = 0; opts[cnt].name; cnt++) { 6391 for (cnt = 0; opts[cnt].name; cnt++) {
6370 create_trace_option_file(tr, &topts[cnt], flags, 6392 create_trace_option_file(tr, &topts[cnt], flags,
@@ -6373,8 +6395,6 @@ create_trace_option_files(struct trace_array *tr, struct tracer *tracer)
6373 "Failed to create trace option: %s", 6395 "Failed to create trace option: %s",
6374 opts[cnt].name); 6396 opts[cnt].name);
6375 } 6397 }
6376
6377 return topts;
6378} 6398}
6379 6399
6380static struct dentry * 6400static struct dentry *
@@ -6552,6 +6572,21 @@ static void init_trace_flags_index(struct trace_array *tr)
6552 tr->trace_flags_index[i] = i; 6572 tr->trace_flags_index[i] = i;
6553} 6573}
6554 6574
6575static void __update_tracer_options(struct trace_array *tr)
6576{
6577 struct tracer *t;
6578
6579 for (t = trace_types; t; t = t->next)
6580 add_tracer_options(tr, t);
6581}
6582
6583static void update_tracer_options(struct trace_array *tr)
6584{
6585 mutex_lock(&trace_types_lock);
6586 __update_tracer_options(tr);
6587 mutex_unlock(&trace_types_lock);
6588}
6589
6555static int instance_mkdir(const char *name) 6590static int instance_mkdir(const char *name)
6556{ 6591{
6557 struct trace_array *tr; 6592 struct trace_array *tr;
@@ -6605,6 +6640,7 @@ static int instance_mkdir(const char *name)
6605 6640
6606 init_tracer_tracefs(tr, tr->dir); 6641 init_tracer_tracefs(tr, tr->dir);
6607 init_trace_flags_index(tr); 6642 init_trace_flags_index(tr);
6643 __update_tracer_options(tr);
6608 6644
6609 list_add(&tr->list, &ftrace_trace_arrays); 6645 list_add(&tr->list, &ftrace_trace_arrays);
6610 6646
@@ -6630,6 +6666,7 @@ static int instance_rmdir(const char *name)
6630 struct trace_array *tr; 6666 struct trace_array *tr;
6631 int found = 0; 6667 int found = 0;
6632 int ret; 6668 int ret;
6669 int i;
6633 6670
6634 mutex_lock(&trace_types_lock); 6671 mutex_lock(&trace_types_lock);
6635 6672
@@ -6655,6 +6692,11 @@ static int instance_rmdir(const char *name)
6655 debugfs_remove_recursive(tr->dir); 6692 debugfs_remove_recursive(tr->dir);
6656 free_trace_buffers(tr); 6693 free_trace_buffers(tr);
6657 6694
6695 for (i = 0; i < tr->nr_topts; i++) {
6696 kfree(tr->topts[i].topts);
6697 }
6698 kfree(tr->topts);
6699
6658 kfree(tr->name); 6700 kfree(tr->name);
6659 kfree(tr); 6701 kfree(tr);
6660 6702
@@ -6877,7 +6919,6 @@ static struct notifier_block trace_module_nb = {
6877static __init int tracer_init_tracefs(void) 6919static __init int tracer_init_tracefs(void)
6878{ 6920{
6879 struct dentry *d_tracer; 6921 struct dentry *d_tracer;
6880 struct tracer *t;
6881 6922
6882 trace_access_lock_init(); 6923 trace_access_lock_init();
6883 6924
@@ -6914,10 +6955,7 @@ static __init int tracer_init_tracefs(void)
6914 6955
6915 create_trace_instances(d_tracer); 6956 create_trace_instances(d_tracer);
6916 6957
6917 mutex_lock(&trace_types_lock); 6958 update_tracer_options(&global_trace);
6918 for (t = trace_types; t; t = t->next)
6919 add_tracer_options(&global_trace, t);
6920 mutex_unlock(&trace_types_lock);
6921 6959
6922 return 0; 6960 return 0;
6923} 6961}
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 423cb48a1d6d..fb8a61c710ea 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -159,6 +159,7 @@ struct trace_array_cpu {
159}; 159};
160 160
161struct tracer; 161struct tracer;
162struct trace_option_dentry;
162 163
163struct trace_buffer { 164struct trace_buffer {
164 struct trace_array *tr; 165 struct trace_array *tr;
@@ -170,6 +171,11 @@ struct trace_buffer {
170 171
171#define TRACE_FLAGS_MAX_SIZE 32 172#define TRACE_FLAGS_MAX_SIZE 32
172 173
174struct trace_options {
175 struct tracer *tracer;
176 struct trace_option_dentry *topts;
177};
178
173/* 179/*
174 * The trace array - an array of per-CPU trace arrays. This is the 180 * The trace array - an array of per-CPU trace arrays. This is the
175 * highest level data structure that individual tracers deal with. 181 * highest level data structure that individual tracers deal with.
@@ -218,6 +224,7 @@ struct trace_array {
218#endif 224#endif
219 int stop_count; 225 int stop_count;
220 int clock_id; 226 int clock_id;
227 int nr_topts;
221 struct tracer *current_trace; 228 struct tracer *current_trace;
222 unsigned int trace_flags; 229 unsigned int trace_flags;
223 unsigned char trace_flags_index[TRACE_FLAGS_MAX_SIZE]; 230 unsigned char trace_flags_index[TRACE_FLAGS_MAX_SIZE];
@@ -227,6 +234,7 @@ struct trace_array {
227 struct dentry *options; 234 struct dentry *options;
228 struct dentry *percpu_dir; 235 struct dentry *percpu_dir;
229 struct dentry *event_dir; 236 struct dentry *event_dir;
237 struct trace_options *topts;
230 struct list_head systems; 238 struct list_head systems;
231 struct list_head events; 239 struct list_head events;
232 cpumask_var_t tracing_cpumask; /* only trace on set CPUs */ 240 cpumask_var_t tracing_cpumask; /* only trace on set CPUs */
@@ -398,7 +406,6 @@ struct tracer {
398 u32 mask, int set); 406 u32 mask, int set);
399 struct tracer *next; 407 struct tracer *next;
400 struct tracer_flags *flags; 408 struct tracer_flags *flags;
401 struct trace_option_dentry *topts;
402 int enabled; 409 int enabled;
403 int ref; 410 int ref;
404 bool print_max; 411 bool print_max;