diff options
author | Jiaxing Wang <hello.wjx@gmail.com> | 2015-11-03 20:14:29 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2015-11-03 21:51:43 -0500 |
commit | a4d1e68823033905de4f927e2e392e21a1c507e3 (patch) | |
tree | ee17db784fb9fce1826f96d6ccfd32cbed30fef4 /kernel/trace/trace.c | |
parent | 627645fdb657dfae5fcf26bbf6a6e1b63751dbc8 (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.c | 45 |
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 | ||
216 | static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata; | 216 | static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata; |
217 | static char *trace_boot_options __initdata; | ||
218 | 217 | ||
219 | static int __init set_trace_boot_options(char *str) | 218 | static 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 | ||
1224 | static void add_tracer_options(struct trace_array *tr, struct tracer *t); | 1222 | static void add_tracer_options(struct trace_array *tr, struct tracer *t); |
1225 | 1223 | ||
1224 | static 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 | */ |
1232 | int register_tracer(struct tracer *type) | 1232 | int __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 | ||
3629 | static 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 | |||
3618 | static ssize_t | 3650 | static ssize_t |
3619 | tracing_trace_options_write(struct file *filp, const char __user *ubuf, | 3651 | tracing_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 | ||