aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-03-19 13:24:42 -0400
committerSteven Rostedt <srostedt@redhat.com>2009-03-19 15:58:38 -0400
commit2fbcdb35aca614f9529a0e7d340146cf0b71684f (patch)
tree02b717134d9d82b1f9a7cebd4e3daccde542cf5c
parent5ef841f6f32dce0b752a4fa0622781ee67a0e874 (diff)
function-graph: calculate function depth within function graph tracer
Currently, the function graph tracer depends on the trace_printk to record the depth. All the information is already there in the trace to calculate function depth, with the exception of having the printk be the first item. But as soon as a entry or exit is reached, then we know the depth. This patch changes the iter->private data from recording a per cpu last_pid, to a structure that holds both the last_pid and the current depth. This data is used to determine the function depth for the printks. Signed-off-by: Steven Rostedt <srostedt@redhat.com>
-rw-r--r--kernel/trace/trace_functions_graph.c91
1 files changed, 69 insertions, 22 deletions
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 2d4d185cd0d8..66ea23b64fe6 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -14,6 +14,11 @@
14#include "trace.h" 14#include "trace.h"
15#include "trace_output.h" 15#include "trace_output.h"
16 16
17struct fgraph_data {
18 pid_t last_pid;
19 int depth;
20};
21
17#define TRACE_GRAPH_INDENT 2 22#define TRACE_GRAPH_INDENT 2
18 23
19/* Flag options */ 24/* Flag options */
@@ -231,16 +236,16 @@ print_graph_proc(struct trace_seq *s, pid_t pid)
231 236
232/* If the pid changed since the last trace, output this event */ 237/* If the pid changed since the last trace, output this event */
233static enum print_line_t 238static enum print_line_t
234verif_pid(struct trace_seq *s, pid_t pid, int cpu, pid_t *last_pids_cpu) 239verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data)
235{ 240{
236 pid_t prev_pid; 241 pid_t prev_pid;
237 pid_t *last_pid; 242 pid_t *last_pid;
238 int ret; 243 int ret;
239 244
240 if (!last_pids_cpu) 245 if (!data)
241 return TRACE_TYPE_HANDLED; 246 return TRACE_TYPE_HANDLED;
242 247
243 last_pid = per_cpu_ptr(last_pids_cpu, cpu); 248 last_pid = &(per_cpu_ptr(data, cpu)->last_pid);
244 249
245 if (*last_pid == pid) 250 if (*last_pid == pid)
246 return TRACE_TYPE_HANDLED; 251 return TRACE_TYPE_HANDLED;
@@ -471,6 +476,7 @@ print_graph_entry_leaf(struct trace_iterator *iter,
471 struct ftrace_graph_ent_entry *entry, 476 struct ftrace_graph_ent_entry *entry,
472 struct ftrace_graph_ret_entry *ret_entry, struct trace_seq *s) 477 struct ftrace_graph_ret_entry *ret_entry, struct trace_seq *s)
473{ 478{
479 struct fgraph_data *data = iter->private;
474 struct ftrace_graph_ret *graph_ret; 480 struct ftrace_graph_ret *graph_ret;
475 struct ftrace_graph_ent *call; 481 struct ftrace_graph_ent *call;
476 unsigned long long duration; 482 unsigned long long duration;
@@ -481,6 +487,18 @@ print_graph_entry_leaf(struct trace_iterator *iter,
481 call = &entry->graph_ent; 487 call = &entry->graph_ent;
482 duration = graph_ret->rettime - graph_ret->calltime; 488 duration = graph_ret->rettime - graph_ret->calltime;
483 489
490 if (data) {
491 int cpu = iter->cpu;
492 int *depth = &(per_cpu_ptr(data, cpu)->depth);
493
494 /*
495 * Comments display at + 1 to depth. Since
496 * this is a leaf function, keep the comments
497 * equal to this depth.
498 */
499 *depth = call->depth - 1;
500 }
501
484 /* Overhead */ 502 /* Overhead */
485 ret = print_graph_overhead(duration, s); 503 ret = print_graph_overhead(duration, s);
486 if (!ret) 504 if (!ret)
@@ -512,12 +530,21 @@ print_graph_entry_leaf(struct trace_iterator *iter,
512} 530}
513 531
514static enum print_line_t 532static enum print_line_t
515print_graph_entry_nested(struct ftrace_graph_ent_entry *entry, 533print_graph_entry_nested(struct trace_iterator *iter,
516 struct trace_seq *s, pid_t pid, int cpu) 534 struct ftrace_graph_ent_entry *entry,
535 struct trace_seq *s, int cpu)
517{ 536{
518 int i;
519 int ret;
520 struct ftrace_graph_ent *call = &entry->graph_ent; 537 struct ftrace_graph_ent *call = &entry->graph_ent;
538 struct fgraph_data *data = iter->private;
539 int ret;
540 int i;
541
542 if (data) {
543 int cpu = iter->cpu;
544 int *depth = &(per_cpu_ptr(data, cpu)->depth);
545
546 *depth = call->depth;
547 }
521 548
522 /* No overhead */ 549 /* No overhead */
523 ret = print_graph_overhead(-1, s); 550 ret = print_graph_overhead(-1, s);
@@ -557,13 +584,13 @@ static enum print_line_t
557print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s, 584print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
558 int type, unsigned long addr) 585 int type, unsigned long addr)
559{ 586{
587 struct fgraph_data *data = iter->private;
560 struct trace_entry *ent = iter->ent; 588 struct trace_entry *ent = iter->ent;
561 pid_t *last_pid = iter->private;
562 int cpu = iter->cpu; 589 int cpu = iter->cpu;
563 int ret; 590 int ret;
564 591
565 /* Pid */ 592 /* Pid */
566 if (verif_pid(s, ent->pid, cpu, last_pid) == TRACE_TYPE_PARTIAL_LINE) 593 if (verif_pid(s, ent->pid, cpu, data) == TRACE_TYPE_PARTIAL_LINE)
567 return TRACE_TYPE_PARTIAL_LINE; 594 return TRACE_TYPE_PARTIAL_LINE;
568 595
569 if (type) { 596 if (type) {
@@ -616,7 +643,7 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
616 if (leaf_ret) 643 if (leaf_ret)
617 return print_graph_entry_leaf(iter, field, leaf_ret, s); 644 return print_graph_entry_leaf(iter, field, leaf_ret, s);
618 else 645 else
619 return print_graph_entry_nested(field, s, iter->ent->pid, cpu); 646 return print_graph_entry_nested(iter, field, s, cpu);
620 647
621} 648}
622 649
@@ -624,11 +651,24 @@ static enum print_line_t
624print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, 651print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
625 struct trace_entry *ent, struct trace_iterator *iter) 652 struct trace_entry *ent, struct trace_iterator *iter)
626{ 653{
627 int i;
628 int ret;
629 int cpu = iter->cpu;
630 pid_t pid = ent->pid;
631 unsigned long long duration = trace->rettime - trace->calltime; 654 unsigned long long duration = trace->rettime - trace->calltime;
655 struct fgraph_data *data = iter->private;
656 pid_t pid = ent->pid;
657 int cpu = iter->cpu;
658 int ret;
659 int i;
660
661 if (data) {
662 int cpu = iter->cpu;
663 int *depth = &(per_cpu_ptr(data, cpu)->depth);
664
665 /*
666 * Comments display at + 1 to depth. This is the
667 * return from a function, we now want the comments
668 * to display at the same level of the bracket.
669 */
670 *depth = trace->depth - 1;
671 }
632 672
633 if (print_graph_prologue(iter, s, 0, 0)) 673 if (print_graph_prologue(iter, s, 0, 0))
634 return TRACE_TYPE_PARTIAL_LINE; 674 return TRACE_TYPE_PARTIAL_LINE;
@@ -675,8 +715,13 @@ static enum print_line_t
675print_graph_comment(struct bprint_entry *trace, struct trace_seq *s, 715print_graph_comment(struct bprint_entry *trace, struct trace_seq *s,
676 struct trace_entry *ent, struct trace_iterator *iter) 716 struct trace_entry *ent, struct trace_iterator *iter)
677{ 717{
678 int i; 718 struct fgraph_data *data = iter->private;
719 int depth = 0;
679 int ret; 720 int ret;
721 int i;
722
723 if (data)
724 depth = per_cpu_ptr(data, iter->cpu)->depth;
680 725
681 if (print_graph_prologue(iter, s, 0, 0)) 726 if (print_graph_prologue(iter, s, 0, 0))
682 return TRACE_TYPE_PARTIAL_LINE; 727 return TRACE_TYPE_PARTIAL_LINE;
@@ -694,8 +739,8 @@ print_graph_comment(struct bprint_entry *trace, struct trace_seq *s,
694 } 739 }
695 740
696 /* Indentation */ 741 /* Indentation */
697 if (trace->depth > 0) 742 if (depth > 0)
698 for (i = 0; i < (trace->depth + 1) * TRACE_GRAPH_INDENT; i++) { 743 for (i = 0; i < (depth + 1) * TRACE_GRAPH_INDENT; i++) {
699 ret = trace_seq_printf(s, " "); 744 ret = trace_seq_printf(s, " ");
700 if (!ret) 745 if (!ret)
701 return TRACE_TYPE_PARTIAL_LINE; 746 return TRACE_TYPE_PARTIAL_LINE;
@@ -780,19 +825,21 @@ static void print_graph_headers(struct seq_file *s)
780 825
781static void graph_trace_open(struct trace_iterator *iter) 826static void graph_trace_open(struct trace_iterator *iter)
782{ 827{
783 /* pid on the last trace processed */ 828 /* pid and depth on the last trace processed */
784 pid_t *last_pid = alloc_percpu(pid_t); 829 struct fgraph_data *data = alloc_percpu(struct fgraph_data);
785 int cpu; 830 int cpu;
786 831
787 if (!last_pid) 832 if (!data)
788 pr_warning("function graph tracer: not enough memory\n"); 833 pr_warning("function graph tracer: not enough memory\n");
789 else 834 else
790 for_each_possible_cpu(cpu) { 835 for_each_possible_cpu(cpu) {
791 pid_t *pid = per_cpu_ptr(last_pid, cpu); 836 pid_t *pid = &(per_cpu_ptr(data, cpu)->last_pid);
837 int *depth = &(per_cpu_ptr(data, cpu)->depth);
792 *pid = -1; 838 *pid = -1;
839 *depth = 0;
793 } 840 }
794 841
795 iter->private = last_pid; 842 iter->private = data;
796} 843}
797 844
798static void graph_trace_close(struct trace_iterator *iter) 845static void graph_trace_close(struct trace_iterator *iter)