aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/trace/ftrace.txt6
-rw-r--r--kernel/trace/trace_functions.c44
2 files changed, 50 insertions, 0 deletions
diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt
index cc9ec57e157c..b937c6e2163c 100644
--- a/Documentation/trace/ftrace.txt
+++ b/Documentation/trace/ftrace.txt
@@ -2437,6 +2437,12 @@ The following commands are supported:
2437 is hit. Perhaps its a function that is called before a tripple 2437 is hit. Perhaps its a function that is called before a tripple
2438 fault happens and does not allow you to get a regular dump. 2438 fault happens and does not allow you to get a regular dump.
2439 2439
2440- cpudump
2441 When the function is hit, it will dump the contents of the ftrace
2442 ring buffer for the current CPU to the console. Unlike the "dump"
2443 command, it only prints out the contents of the ring buffer for the
2444 CPU that executed the function that triggered the dump.
2445
2440trace_pipe 2446trace_pipe
2441---------- 2447----------
2442 2448
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index d7c8719734b8..b863f93b30f3 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -297,6 +297,14 @@ ftrace_dump_probe(unsigned long ip, unsigned long parent_ip, void **data)
297 ftrace_dump(DUMP_ALL); 297 ftrace_dump(DUMP_ALL);
298} 298}
299 299
300/* Only dump the current CPU buffer. */
301static void
302ftrace_cpudump_probe(unsigned long ip, unsigned long parent_ip, void **data)
303{
304 if (update_count(data))
305 ftrace_dump(DUMP_ORIG);
306}
307
300static int 308static int
301ftrace_probe_print(const char *name, struct seq_file *m, 309ftrace_probe_print(const char *name, struct seq_file *m,
302 unsigned long ip, void *data) 310 unsigned long ip, void *data)
@@ -341,6 +349,13 @@ ftrace_dump_print(struct seq_file *m, unsigned long ip,
341 return ftrace_probe_print("dump", m, ip, data); 349 return ftrace_probe_print("dump", m, ip, data);
342} 350}
343 351
352static int
353ftrace_cpudump_print(struct seq_file *m, unsigned long ip,
354 struct ftrace_probe_ops *ops, void *data)
355{
356 return ftrace_probe_print("cpudump", m, ip, data);
357}
358
344static struct ftrace_probe_ops traceon_count_probe_ops = { 359static struct ftrace_probe_ops traceon_count_probe_ops = {
345 .func = ftrace_traceon_count, 360 .func = ftrace_traceon_count,
346 .print = ftrace_traceon_print, 361 .print = ftrace_traceon_print,
@@ -361,6 +376,11 @@ static struct ftrace_probe_ops dump_probe_ops = {
361 .print = ftrace_dump_print, 376 .print = ftrace_dump_print,
362}; 377};
363 378
379static struct ftrace_probe_ops cpudump_probe_ops = {
380 .func = ftrace_cpudump_probe,
381 .print = ftrace_cpudump_print,
382};
383
364static struct ftrace_probe_ops traceon_probe_ops = { 384static struct ftrace_probe_ops traceon_probe_ops = {
365 .func = ftrace_traceon, 385 .func = ftrace_traceon,
366 .print = ftrace_traceon_print, 386 .print = ftrace_traceon_print,
@@ -457,6 +477,19 @@ ftrace_dump_callback(struct ftrace_hash *hash,
457 "1", enable); 477 "1", enable);
458} 478}
459 479
480static int
481ftrace_cpudump_callback(struct ftrace_hash *hash,
482 char *glob, char *cmd, char *param, int enable)
483{
484 struct ftrace_probe_ops *ops;
485
486 ops = &cpudump_probe_ops;
487
488 /* Only dump once. */
489 return ftrace_trace_probe_callback(ops, hash, glob, cmd,
490 "1", enable);
491}
492
460static struct ftrace_func_command ftrace_traceon_cmd = { 493static struct ftrace_func_command ftrace_traceon_cmd = {
461 .name = "traceon", 494 .name = "traceon",
462 .func = ftrace_trace_onoff_callback, 495 .func = ftrace_trace_onoff_callback,
@@ -477,6 +510,11 @@ static struct ftrace_func_command ftrace_dump_cmd = {
477 .func = ftrace_dump_callback, 510 .func = ftrace_dump_callback,
478}; 511};
479 512
513static struct ftrace_func_command ftrace_cpudump_cmd = {
514 .name = "cpudump",
515 .func = ftrace_cpudump_callback,
516};
517
480static int __init init_func_cmd_traceon(void) 518static int __init init_func_cmd_traceon(void)
481{ 519{
482 int ret; 520 int ret;
@@ -497,8 +535,14 @@ static int __init init_func_cmd_traceon(void)
497 if (ret) 535 if (ret)
498 goto out_free_stacktrace; 536 goto out_free_stacktrace;
499 537
538 ret = register_ftrace_command(&ftrace_cpudump_cmd);
539 if (ret)
540 goto out_free_dump;
541
500 return 0; 542 return 0;
501 543
544 out_free_dump:
545 unregister_ftrace_command(&ftrace_dump_cmd);
502 out_free_stacktrace: 546 out_free_stacktrace:
503 unregister_ftrace_command(&ftrace_stacktrace_cmd); 547 unregister_ftrace_command(&ftrace_stacktrace_cmd);
504 out_free_traceon: 548 out_free_traceon: