diff options
Diffstat (limited to 'kernel/trace/trace_functions.c')
-rw-r--r-- | kernel/trace/trace_functions.c | 103 |
1 files changed, 98 insertions, 5 deletions
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index c4d6d7191988..b863f93b30f3 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c | |||
@@ -290,6 +290,21 @@ ftrace_stacktrace_count(unsigned long ip, unsigned long parent_ip, void **data) | |||
290 | trace_dump_stack(STACK_SKIP); | 290 | trace_dump_stack(STACK_SKIP); |
291 | } | 291 | } |
292 | 292 | ||
293 | static void | ||
294 | ftrace_dump_probe(unsigned long ip, unsigned long parent_ip, void **data) | ||
295 | { | ||
296 | if (update_count(data)) | ||
297 | ftrace_dump(DUMP_ALL); | ||
298 | } | ||
299 | |||
300 | /* Only dump the current CPU buffer. */ | ||
301 | static void | ||
302 | ftrace_cpudump_probe(unsigned long ip, unsigned long parent_ip, void **data) | ||
303 | { | ||
304 | if (update_count(data)) | ||
305 | ftrace_dump(DUMP_ORIG); | ||
306 | } | ||
307 | |||
293 | static int | 308 | static int |
294 | ftrace_probe_print(const char *name, struct seq_file *m, | 309 | ftrace_probe_print(const char *name, struct seq_file *m, |
295 | unsigned long ip, void *data) | 310 | unsigned long ip, void *data) |
@@ -327,6 +342,20 @@ ftrace_stacktrace_print(struct seq_file *m, unsigned long ip, | |||
327 | return ftrace_probe_print("stacktrace", m, ip, data); | 342 | return ftrace_probe_print("stacktrace", m, ip, data); |
328 | } | 343 | } |
329 | 344 | ||
345 | static int | ||
346 | ftrace_dump_print(struct seq_file *m, unsigned long ip, | ||
347 | struct ftrace_probe_ops *ops, void *data) | ||
348 | { | ||
349 | return ftrace_probe_print("dump", m, ip, data); | ||
350 | } | ||
351 | |||
352 | static int | ||
353 | ftrace_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 | |||
330 | static struct ftrace_probe_ops traceon_count_probe_ops = { | 359 | static struct ftrace_probe_ops traceon_count_probe_ops = { |
331 | .func = ftrace_traceon_count, | 360 | .func = ftrace_traceon_count, |
332 | .print = ftrace_traceon_print, | 361 | .print = ftrace_traceon_print, |
@@ -342,6 +371,16 @@ static struct ftrace_probe_ops stacktrace_count_probe_ops = { | |||
342 | .print = ftrace_stacktrace_print, | 371 | .print = ftrace_stacktrace_print, |
343 | }; | 372 | }; |
344 | 373 | ||
374 | static struct ftrace_probe_ops dump_probe_ops = { | ||
375 | .func = ftrace_dump_probe, | ||
376 | .print = ftrace_dump_print, | ||
377 | }; | ||
378 | |||
379 | static struct ftrace_probe_ops cpudump_probe_ops = { | ||
380 | .func = ftrace_cpudump_probe, | ||
381 | .print = ftrace_cpudump_print, | ||
382 | }; | ||
383 | |||
345 | static struct ftrace_probe_ops traceon_probe_ops = { | 384 | static struct ftrace_probe_ops traceon_probe_ops = { |
346 | .func = ftrace_traceon, | 385 | .func = ftrace_traceon, |
347 | .print = ftrace_traceon_print, | 386 | .print = ftrace_traceon_print, |
@@ -425,6 +464,32 @@ ftrace_stacktrace_callback(struct ftrace_hash *hash, | |||
425 | param, enable); | 464 | param, enable); |
426 | } | 465 | } |
427 | 466 | ||
467 | static int | ||
468 | ftrace_dump_callback(struct ftrace_hash *hash, | ||
469 | char *glob, char *cmd, char *param, int enable) | ||
470 | { | ||
471 | struct ftrace_probe_ops *ops; | ||
472 | |||
473 | ops = &dump_probe_ops; | ||
474 | |||
475 | /* Only dump once. */ | ||
476 | return ftrace_trace_probe_callback(ops, hash, glob, cmd, | ||
477 | "1", enable); | ||
478 | } | ||
479 | |||
480 | static int | ||
481 | ftrace_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 | |||
428 | static struct ftrace_func_command ftrace_traceon_cmd = { | 493 | static struct ftrace_func_command ftrace_traceon_cmd = { |
429 | .name = "traceon", | 494 | .name = "traceon", |
430 | .func = ftrace_trace_onoff_callback, | 495 | .func = ftrace_trace_onoff_callback, |
@@ -440,6 +505,16 @@ static struct ftrace_func_command ftrace_stacktrace_cmd = { | |||
440 | .func = ftrace_stacktrace_callback, | 505 | .func = ftrace_stacktrace_callback, |
441 | }; | 506 | }; |
442 | 507 | ||
508 | static struct ftrace_func_command ftrace_dump_cmd = { | ||
509 | .name = "dump", | ||
510 | .func = ftrace_dump_callback, | ||
511 | }; | ||
512 | |||
513 | static struct ftrace_func_command ftrace_cpudump_cmd = { | ||
514 | .name = "cpudump", | ||
515 | .func = ftrace_cpudump_callback, | ||
516 | }; | ||
517 | |||
443 | static int __init init_func_cmd_traceon(void) | 518 | static int __init init_func_cmd_traceon(void) |
444 | { | 519 | { |
445 | int ret; | 520 | int ret; |
@@ -450,13 +525,31 @@ static int __init init_func_cmd_traceon(void) | |||
450 | 525 | ||
451 | ret = register_ftrace_command(&ftrace_traceon_cmd); | 526 | ret = register_ftrace_command(&ftrace_traceon_cmd); |
452 | if (ret) | 527 | if (ret) |
453 | unregister_ftrace_command(&ftrace_traceoff_cmd); | 528 | goto out_free_traceoff; |
454 | 529 | ||
455 | ret = register_ftrace_command(&ftrace_stacktrace_cmd); | 530 | ret = register_ftrace_command(&ftrace_stacktrace_cmd); |
456 | if (ret) { | 531 | if (ret) |
457 | unregister_ftrace_command(&ftrace_traceoff_cmd); | 532 | goto out_free_traceon; |
458 | unregister_ftrace_command(&ftrace_traceon_cmd); | 533 | |
459 | } | 534 | ret = register_ftrace_command(&ftrace_dump_cmd); |
535 | if (ret) | ||
536 | goto out_free_stacktrace; | ||
537 | |||
538 | ret = register_ftrace_command(&ftrace_cpudump_cmd); | ||
539 | if (ret) | ||
540 | goto out_free_dump; | ||
541 | |||
542 | return 0; | ||
543 | |||
544 | out_free_dump: | ||
545 | unregister_ftrace_command(&ftrace_dump_cmd); | ||
546 | out_free_stacktrace: | ||
547 | unregister_ftrace_command(&ftrace_stacktrace_cmd); | ||
548 | out_free_traceon: | ||
549 | unregister_ftrace_command(&ftrace_traceon_cmd); | ||
550 | out_free_traceoff: | ||
551 | unregister_ftrace_command(&ftrace_traceoff_cmd); | ||
552 | |||
460 | return ret; | 553 | return ret; |
461 | } | 554 | } |
462 | #else | 555 | #else |