aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorJiaxing Wang <hello.wjx@gmail.com>2015-11-03 20:14:29 -0500
committerSteven Rostedt <rostedt@goodmis.org>2015-11-03 21:51:43 -0500
commita4d1e68823033905de4f927e2e392e21a1c507e3 (patch)
treeee17db784fb9fce1826f96d6ccfd32cbed30fef4 /kernel/trace/trace.c
parent627645fdb657dfae5fcf26bbf6a6e1b63751dbc8 (diff)
tracing: Apply tracer specific options from kernel command line.
Currently, the trace_options parameter is only applied in tracer_alloc_buffers() when global_trace.current_trace is nop_trace, so a tracer specific option will not be applied even when the specific tracer is also enabled from kernel command line. For example, the 'func_stack_trace' option can't be enabled with the following kernel parameter: ftrace=function ftrace_filter=kfree trace_options=func_stack_trace We can enable tracer specific options by simply apply the options again if the specific tracer is also supplied from command line and started in register_tracer(). To make trace_boot_options_buf can be parsed again, a comma and a space is put back if they were replaced by strsep and strstrip respectively. Also make register_tracer() be __init to access the __init data, and in fact register_tracer is only called from __init code. Link: http://lkml.kernel.org/r/1446599669-9294-1-git-send-email-hello.wjx@gmail.com Signed-off-by: Jiaxing Wang <hello.wjx@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 6459e141aac3..7fe7cc987dab 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -214,12 +214,10 @@ __setup("alloc_snapshot", boot_alloc_snapshot);
214 214
215 215
216static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata; 216static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata;
217static char *trace_boot_options __initdata;
218 217
219static int __init set_trace_boot_options(char *str) 218static int __init set_trace_boot_options(char *str)
220{ 219{
221 strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE); 220 strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE);
222 trace_boot_options = trace_boot_options_buf;
223 return 0; 221 return 0;
224} 222}
225__setup("trace_options=", set_trace_boot_options); 223__setup("trace_options=", set_trace_boot_options);
@@ -1223,13 +1221,15 @@ static inline int run_tracer_selftest(struct tracer *type)
1223 1221
1224static void add_tracer_options(struct trace_array *tr, struct tracer *t); 1222static void add_tracer_options(struct trace_array *tr, struct tracer *t);
1225 1223
1224static void __init apply_trace_boot_options(void);
1225
1226/** 1226/**
1227 * register_tracer - register a tracer with the ftrace system. 1227 * register_tracer - register a tracer with the ftrace system.
1228 * @type - the plugin for the tracer 1228 * @type - the plugin for the tracer
1229 * 1229 *
1230 * Register a new plugin tracer. 1230 * Register a new plugin tracer.
1231 */ 1231 */
1232int register_tracer(struct tracer *type) 1232int __init register_tracer(struct tracer *type)
1233{ 1233{
1234 struct tracer *t; 1234 struct tracer *t;
1235 int ret = 0; 1235 int ret = 0;
@@ -1288,6 +1288,9 @@ int register_tracer(struct tracer *type)
1288 /* Do we want this tracer to start on bootup? */ 1288 /* Do we want this tracer to start on bootup? */
1289 tracing_set_tracer(&global_trace, type->name); 1289 tracing_set_tracer(&global_trace, type->name);
1290 default_bootup_tracer = NULL; 1290 default_bootup_tracer = NULL;
1291
1292 apply_trace_boot_options();
1293
1291 /* disable other selftests, since this will break it. */ 1294 /* disable other selftests, since this will break it. */
1292 tracing_selftest_disabled = true; 1295 tracing_selftest_disabled = true;
1293#ifdef CONFIG_FTRACE_STARTUP_TEST 1296#ifdef CONFIG_FTRACE_STARTUP_TEST
@@ -3589,6 +3592,7 @@ static int trace_set_options(struct trace_array *tr, char *option)
3589 int neg = 0; 3592 int neg = 0;
3590 int ret = -ENODEV; 3593 int ret = -ENODEV;
3591 int i; 3594 int i;
3595 size_t orig_len = strlen(option);
3592 3596
3593 cmp = strstrip(option); 3597 cmp = strstrip(option);
3594 3598
@@ -3612,9 +3616,37 @@ static int trace_set_options(struct trace_array *tr, char *option)
3612 3616
3613 mutex_unlock(&trace_types_lock); 3617 mutex_unlock(&trace_types_lock);
3614 3618
3619 /*
3620 * If the first trailing whitespace is replaced with '\0' by strstrip,
3621 * turn it back into a space.
3622 */
3623 if (orig_len > strlen(option))
3624 option[strlen(option)] = ' ';
3625
3615 return ret; 3626 return ret;
3616} 3627}
3617 3628
3629static void __init apply_trace_boot_options(void)
3630{
3631 char *buf = trace_boot_options_buf;
3632 char *option;
3633
3634 while (true) {
3635 option = strsep(&buf, ",");
3636
3637 if (!option)
3638 break;
3639 if (!*option)
3640 continue;
3641
3642 trace_set_options(&global_trace, option);
3643
3644 /* Put back the comma to allow this to be called again */
3645 if (buf)
3646 *(buf - 1) = ',';
3647 }
3648}
3649
3618static ssize_t 3650static ssize_t
3619tracing_trace_options_write(struct file *filp, const char __user *ubuf, 3651tracing_trace_options_write(struct file *filp, const char __user *ubuf,
3620 size_t cnt, loff_t *ppos) 3652 size_t cnt, loff_t *ppos)
@@ -7248,12 +7280,7 @@ __init static int tracer_alloc_buffers(void)
7248 INIT_LIST_HEAD(&global_trace.events); 7280 INIT_LIST_HEAD(&global_trace.events);
7249 list_add(&global_trace.list, &ftrace_trace_arrays); 7281 list_add(&global_trace.list, &ftrace_trace_arrays);
7250 7282
7251 while (trace_boot_options) { 7283 apply_trace_boot_options();
7252 char *option;
7253
7254 option = strsep(&trace_boot_options, ",");
7255 trace_set_options(&global_trace, option);
7256 }
7257 7284
7258 register_snapshot_cmd(); 7285 register_snapshot_cmd();
7259 7286