aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_functions_graph.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-09-11 00:30:26 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-09-11 10:59:49 -0400
commit49ff590390a22c49e9063dcdec4cd5903127526b (patch)
treef30913673a9d89d2f67cdafeed03afe127511713 /kernel/trace/trace_functions_graph.c
parentfc06b8520b3bf9aaeb2e27debe6719c215bd4916 (diff)
tracing: add latency format to function_graph tracer
While debugging something with the function_graph tracer, I found the need to see the preempt count of the traces. Unfortunately, since the function graph tracer has its own output formatting, it does not honor the latency-format option. This patch makes the function_graph tracer honor the latency-format option, but still keeps control of the output. But now we have the same details that the latency-format supplies. # tracer: function_graph # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / # |||| # CPU|||| DURATION FUNCTION CALLS # | |||| | | | | | | 3) d..1 1.333 us | idle_cpu(); 3) d.h1 | tick_check_idle() { 3) d.h1 0.550 us | tick_check_oneshot_broadcast(); 3) d.h1 | tick_nohz_stop_idle() { 3) d.h1 | ktime_get() { 3) d.h1 | ktime_get_ts() { Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_functions_graph.c')
-rw-r--r--kernel/trace/trace_functions_graph.c74
1 files changed, 68 insertions, 6 deletions
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index b3749a2c3132..ee791a9650c5 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -364,6 +364,29 @@ print_graph_proc(struct trace_seq *s, pid_t pid)
364} 364}
365 365
366 366
367static enum print_line_t
368print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
369{
370 int hardirq, softirq;
371
372 hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
373 softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
374
375 if (!trace_seq_printf(s, " %c%c%c",
376 (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
377 (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
378 'X' : '.',
379 (entry->flags & TRACE_FLAG_NEED_RESCHED) ?
380 'N' : '.',
381 (hardirq && softirq) ? 'H' :
382 hardirq ? 'h' : softirq ? 's' : '.'))
383 return 0;
384
385 if (entry->preempt_count)
386 return trace_seq_printf(s, "%x", entry->preempt_count);
387 return trace_seq_puts(s, ".");
388}
389
367/* If the pid changed since the last trace, output this event */ 390/* If the pid changed since the last trace, output this event */
368static enum print_line_t 391static enum print_line_t
369verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data) 392verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data)
@@ -521,6 +544,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
521 if (ret == TRACE_TYPE_PARTIAL_LINE) 544 if (ret == TRACE_TYPE_PARTIAL_LINE)
522 return TRACE_TYPE_PARTIAL_LINE; 545 return TRACE_TYPE_PARTIAL_LINE;
523 } 546 }
547
524 /* Proc */ 548 /* Proc */
525 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) { 549 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
526 ret = print_graph_proc(s, pid); 550 ret = print_graph_proc(s, pid);
@@ -758,6 +782,13 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
758 return TRACE_TYPE_PARTIAL_LINE; 782 return TRACE_TYPE_PARTIAL_LINE;
759 } 783 }
760 784
785 /* Latency format */
786 if (trace_flags & TRACE_ITER_LATENCY_FMT) {
787 ret = print_graph_lat_fmt(s, ent);
788 if (ret == TRACE_TYPE_PARTIAL_LINE)
789 return TRACE_TYPE_PARTIAL_LINE;
790 }
791
761 return 0; 792 return 0;
762} 793}
763 794
@@ -952,28 +983,59 @@ print_graph_function(struct trace_iterator *iter)
952 return TRACE_TYPE_HANDLED; 983 return TRACE_TYPE_HANDLED;
953} 984}
954 985
986static void print_lat_header(struct seq_file *s)
987{
988 static const char spaces[] = " " /* 16 spaces */
989 " " /* 4 spaces */
990 " "; /* 17 spaces */
991 int size = 0;
992
993 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
994 size += 16;
995 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
996 size += 4;
997 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
998 size += 17;
999
1000 seq_printf(s, "#%.*s _-----=> irqs-off \n", size, spaces);
1001 seq_printf(s, "#%.*s / _----=> need-resched \n", size, spaces);
1002 seq_printf(s, "#%.*s| / _---=> hardirq/softirq \n", size, spaces);
1003 seq_printf(s, "#%.*s|| / _--=> preempt-depth \n", size, spaces);
1004 seq_printf(s, "#%.*s||| / \n", size, spaces);
1005 seq_printf(s, "#%.*s|||| \n", size, spaces);
1006}
1007
955static void print_graph_headers(struct seq_file *s) 1008static void print_graph_headers(struct seq_file *s)
956{ 1009{
1010 int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
1011
1012 if (lat)
1013 print_lat_header(s);
1014
957 /* 1st line */ 1015 /* 1st line */
958 seq_printf(s, "# "); 1016 seq_printf(s, "#");
959 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) 1017 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
960 seq_printf(s, " TIME "); 1018 seq_printf(s, " TIME ");
961 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) 1019 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
962 seq_printf(s, "CPU"); 1020 seq_printf(s, " CPU");
963 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1021 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
964 seq_printf(s, " TASK/PID "); 1022 seq_printf(s, " TASK/PID ");
1023 if (lat)
1024 seq_printf(s, "||||");
965 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 1025 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
966 seq_printf(s, " DURATION "); 1026 seq_printf(s, " DURATION ");
967 seq_printf(s, " FUNCTION CALLS\n"); 1027 seq_printf(s, " FUNCTION CALLS\n");
968 1028
969 /* 2nd line */ 1029 /* 2nd line */
970 seq_printf(s, "# "); 1030 seq_printf(s, "#");
971 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) 1031 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
972 seq_printf(s, " | "); 1032 seq_printf(s, " | ");
973 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) 1033 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
974 seq_printf(s, "| "); 1034 seq_printf(s, " | ");
975 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1035 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
976 seq_printf(s, " | | "); 1036 seq_printf(s, " | | ");
1037 if (lat)
1038 seq_printf(s, "||||");
977 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 1039 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
978 seq_printf(s, " | | "); 1040 seq_printf(s, " | | ");
979 seq_printf(s, " | | | |\n"); 1041 seq_printf(s, " | | | |\n");