diff options
Diffstat (limited to 'kernel/trace/trace_functions.c')
| -rw-r--r-- | kernel/trace/trace_functions.c | 105 |
1 files changed, 99 insertions, 6 deletions
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index c4d6d7191988..38fe1483c508 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c | |||
| @@ -199,7 +199,7 @@ static int func_set_flag(u32 old_flags, u32 bit, int set) | |||
| 199 | return 0; | 199 | return 0; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static struct tracer function_trace __read_mostly = | 202 | static struct tracer function_trace __tracer_data = |
| 203 | { | 203 | { |
| 204 | .name = "function", | 204 | .name = "function", |
| 205 | .init = function_trace_init, | 205 | .init = function_trace_init, |
| @@ -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 |
