diff options
| author | Stanislav Fomichev <stfomichev@yandex-team.ru> | 2014-07-18 07:17:27 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2014-07-18 15:48:52 -0400 |
| commit | 6508fa761c330a1d2b4ae36199d08dbcb70e3ddb (patch) | |
| tree | c5c76da37fddea1160d8a18ace06d89da3e20ec9 | |
| parent | 021c5b34452d52e51664f09b98cd50c5495e74b6 (diff) | |
tracing: let user specify tracing_thresh after selecting function_graph
Currently, tracing_thresh works only if we specify it before selecting
function_graph tracer. If we do the opposite, tracing_thresh will change
it's value, but it will not be applied.
To fix it, we add update_thresh callback which is called whenever
tracing_thresh is updated and for function_graph tracer we register
handler which reinitializes tracer depending on tracing_thresh.
Link: http://lkml.kernel.org/p/20140718111727.GA3206@stfomichev-desktop.yandex.net
Signed-off-by: Stanislav Fomichev <stfomichev@yandex-team.ru>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
| -rw-r--r-- | kernel/trace/trace.c | 65 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_functions_graph.c | 7 |
3 files changed, 67 insertions, 7 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 4a343db45d4e..2752147ed317 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -4201,10 +4201,9 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf, | |||
| 4201 | } | 4201 | } |
| 4202 | 4202 | ||
| 4203 | static ssize_t | 4203 | static ssize_t |
| 4204 | tracing_max_lat_read(struct file *filp, char __user *ubuf, | 4204 | tracing_nsecs_read(unsigned long *ptr, char __user *ubuf, |
| 4205 | size_t cnt, loff_t *ppos) | 4205 | size_t cnt, loff_t *ppos) |
| 4206 | { | 4206 | { |
| 4207 | unsigned long *ptr = filp->private_data; | ||
| 4208 | char buf[64]; | 4207 | char buf[64]; |
| 4209 | int r; | 4208 | int r; |
| 4210 | 4209 | ||
| @@ -4216,10 +4215,9 @@ tracing_max_lat_read(struct file *filp, char __user *ubuf, | |||
| 4216 | } | 4215 | } |
| 4217 | 4216 | ||
| 4218 | static ssize_t | 4217 | static ssize_t |
| 4219 | tracing_max_lat_write(struct file *filp, const char __user *ubuf, | 4218 | tracing_nsecs_write(unsigned long *ptr, const char __user *ubuf, |
| 4220 | size_t cnt, loff_t *ppos) | 4219 | size_t cnt, loff_t *ppos) |
| 4221 | { | 4220 | { |
| 4222 | unsigned long *ptr = filp->private_data; | ||
| 4223 | unsigned long val; | 4221 | unsigned long val; |
| 4224 | int ret; | 4222 | int ret; |
| 4225 | 4223 | ||
| @@ -4232,6 +4230,52 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf, | |||
| 4232 | return cnt; | 4230 | return cnt; |
| 4233 | } | 4231 | } |
| 4234 | 4232 | ||
| 4233 | static ssize_t | ||
| 4234 | tracing_thresh_read(struct file *filp, char __user *ubuf, | ||
| 4235 | size_t cnt, loff_t *ppos) | ||
| 4236 | { | ||
| 4237 | return tracing_nsecs_read(&tracing_thresh, ubuf, cnt, ppos); | ||
| 4238 | } | ||
| 4239 | |||
| 4240 | static ssize_t | ||
| 4241 | tracing_thresh_write(struct file *filp, const char __user *ubuf, | ||
| 4242 | size_t cnt, loff_t *ppos) | ||
| 4243 | { | ||
| 4244 | struct trace_array *tr = filp->private_data; | ||
| 4245 | int ret; | ||
| 4246 | |||
| 4247 | mutex_lock(&trace_types_lock); | ||
| 4248 | ret = tracing_nsecs_write(&tracing_thresh, ubuf, cnt, ppos); | ||
| 4249 | if (ret < 0) | ||
| 4250 | goto out; | ||
| 4251 | |||
| 4252 | if (tr->current_trace->update_thresh) { | ||
| 4253 | ret = tr->current_trace->update_thresh(tr); | ||
| 4254 | if (ret < 0) | ||
| 4255 | goto out; | ||
| 4256 | } | ||
| 4257 | |||
| 4258 | ret = cnt; | ||
| 4259 | out: | ||
| 4260 | mutex_unlock(&trace_types_lock); | ||
| 4261 | |||
| 4262 | return ret; | ||
| 4263 | } | ||
| 4264 | |||
| 4265 | static ssize_t | ||
| 4266 | tracing_max_lat_read(struct file *filp, char __user *ubuf, | ||
| 4267 | size_t cnt, loff_t *ppos) | ||
| 4268 | { | ||
| 4269 | return tracing_nsecs_read(filp->private_data, ubuf, cnt, ppos); | ||
| 4270 | } | ||
| 4271 | |||
| 4272 | static ssize_t | ||
| 4273 | tracing_max_lat_write(struct file *filp, const char __user *ubuf, | ||
| 4274 | size_t cnt, loff_t *ppos) | ||
| 4275 | { | ||
| 4276 | return tracing_nsecs_write(filp->private_data, ubuf, cnt, ppos); | ||
| 4277 | } | ||
| 4278 | |||
| 4235 | static int tracing_open_pipe(struct inode *inode, struct file *filp) | 4279 | static int tracing_open_pipe(struct inode *inode, struct file *filp) |
| 4236 | { | 4280 | { |
| 4237 | struct trace_array *tr = inode->i_private; | 4281 | struct trace_array *tr = inode->i_private; |
| @@ -5133,6 +5177,13 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp) | |||
| 5133 | #endif /* CONFIG_TRACER_SNAPSHOT */ | 5177 | #endif /* CONFIG_TRACER_SNAPSHOT */ |
| 5134 | 5178 | ||
| 5135 | 5179 | ||
| 5180 | static const struct file_operations tracing_thresh_fops = { | ||
| 5181 | .open = tracing_open_generic, | ||
| 5182 | .read = tracing_thresh_read, | ||
| 5183 | .write = tracing_thresh_write, | ||
| 5184 | .llseek = generic_file_llseek, | ||
| 5185 | }; | ||
| 5186 | |||
| 5136 | static const struct file_operations tracing_max_lat_fops = { | 5187 | static const struct file_operations tracing_max_lat_fops = { |
| 5137 | .open = tracing_open_generic, | 5188 | .open = tracing_open_generic, |
| 5138 | .read = tracing_max_lat_read, | 5189 | .read = tracing_max_lat_read, |
| @@ -6494,7 +6545,7 @@ static __init int tracer_init_debugfs(void) | |||
| 6494 | init_tracer_debugfs(&global_trace, d_tracer); | 6545 | init_tracer_debugfs(&global_trace, d_tracer); |
| 6495 | 6546 | ||
| 6496 | trace_create_file("tracing_thresh", 0644, d_tracer, | 6547 | trace_create_file("tracing_thresh", 0644, d_tracer, |
| 6497 | &tracing_thresh, &tracing_max_lat_fops); | 6548 | &global_trace, &tracing_thresh_fops); |
| 6498 | 6549 | ||
| 6499 | trace_create_file("README", 0444, d_tracer, | 6550 | trace_create_file("README", 0444, d_tracer, |
| 6500 | NULL, &tracing_readme_fops); | 6551 | NULL, &tracing_readme_fops); |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 9258f5a815db..385391fb1d3b 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -339,6 +339,7 @@ struct tracer_flags { | |||
| 339 | * @reset: called when one switches to another tracer | 339 | * @reset: called when one switches to another tracer |
| 340 | * @start: called when tracing is unpaused (echo 1 > tracing_enabled) | 340 | * @start: called when tracing is unpaused (echo 1 > tracing_enabled) |
| 341 | * @stop: called when tracing is paused (echo 0 > tracing_enabled) | 341 | * @stop: called when tracing is paused (echo 0 > tracing_enabled) |
| 342 | * @update_thresh: called when tracing_thresh is updated | ||
| 342 | * @open: called when the trace file is opened | 343 | * @open: called when the trace file is opened |
| 343 | * @pipe_open: called when the trace_pipe file is opened | 344 | * @pipe_open: called when the trace_pipe file is opened |
| 344 | * @close: called when the trace file is released | 345 | * @close: called when the trace file is released |
| @@ -357,6 +358,7 @@ struct tracer { | |||
| 357 | void (*reset)(struct trace_array *tr); | 358 | void (*reset)(struct trace_array *tr); |
| 358 | void (*start)(struct trace_array *tr); | 359 | void (*start)(struct trace_array *tr); |
| 359 | void (*stop)(struct trace_array *tr); | 360 | void (*stop)(struct trace_array *tr); |
| 361 | int (*update_thresh)(struct trace_array *tr); | ||
| 360 | void (*open)(struct trace_iterator *iter); | 362 | void (*open)(struct trace_iterator *iter); |
| 361 | void (*pipe_open)(struct trace_iterator *iter); | 363 | void (*pipe_open)(struct trace_iterator *iter); |
| 362 | void (*close)(struct trace_iterator *iter); | 364 | void (*close)(struct trace_iterator *iter); |
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 2c944e6c4a9d..74d98820497c 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c | |||
| @@ -475,6 +475,12 @@ static void graph_trace_reset(struct trace_array *tr) | |||
| 475 | unregister_ftrace_graph(); | 475 | unregister_ftrace_graph(); |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | int graph_trace_update_thresh(struct trace_array *tr) | ||
| 479 | { | ||
| 480 | graph_trace_reset(tr); | ||
| 481 | return graph_trace_init(tr); | ||
| 482 | } | ||
| 483 | |||
| 478 | static int max_bytes_for_cpu; | 484 | static int max_bytes_for_cpu; |
| 479 | 485 | ||
| 480 | static enum print_line_t | 486 | static enum print_line_t |
| @@ -1525,6 +1531,7 @@ static struct trace_event graph_trace_ret_event = { | |||
| 1525 | 1531 | ||
| 1526 | static struct tracer graph_trace __tracer_data = { | 1532 | static struct tracer graph_trace __tracer_data = { |
| 1527 | .name = "function_graph", | 1533 | .name = "function_graph", |
| 1534 | .update_thresh = graph_trace_update_thresh, | ||
| 1528 | .open = graph_trace_open, | 1535 | .open = graph_trace_open, |
| 1529 | .pipe_open = graph_trace_open, | 1536 | .pipe_open = graph_trace_open, |
| 1530 | .close = graph_trace_close, | 1537 | .close = graph_trace_close, |
