aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_functions_graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_functions_graph.c')
-rw-r--r--kernel/trace/trace_functions_graph.c63
1 files changed, 41 insertions, 22 deletions
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index ca98445782ac..92382af7a213 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -83,13 +83,18 @@ static struct tracer_opt trace_opts[] = {
83 { TRACER_OPT(funcgraph-irqs, TRACE_GRAPH_PRINT_IRQS) }, 83 { TRACER_OPT(funcgraph-irqs, TRACE_GRAPH_PRINT_IRQS) },
84 /* Display function name after trailing } */ 84 /* Display function name after trailing } */
85 { TRACER_OPT(funcgraph-tail, TRACE_GRAPH_PRINT_TAIL) }, 85 { TRACER_OPT(funcgraph-tail, TRACE_GRAPH_PRINT_TAIL) },
86 /* Include sleep time (scheduled out) between entry and return */
87 { TRACER_OPT(sleep-time, TRACE_GRAPH_SLEEP_TIME) },
88 /* Include time within nested functions */
89 { TRACER_OPT(graph-time, TRACE_GRAPH_GRAPH_TIME) },
86 { } /* Empty entry */ 90 { } /* Empty entry */
87}; 91};
88 92
89static struct tracer_flags tracer_flags = { 93static struct tracer_flags tracer_flags = {
90 /* Don't display overruns, proc, or tail by default */ 94 /* Don't display overruns, proc, or tail by default */
91 .val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD | 95 .val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD |
92 TRACE_GRAPH_PRINT_DURATION | TRACE_GRAPH_PRINT_IRQS, 96 TRACE_GRAPH_PRINT_DURATION | TRACE_GRAPH_PRINT_IRQS |
97 TRACE_GRAPH_SLEEP_TIME | TRACE_GRAPH_GRAPH_TIME,
93 .opts = trace_opts 98 .opts = trace_opts
94}; 99};
95 100
@@ -107,8 +112,8 @@ enum {
107}; 112};
108 113
109static void 114static void
110print_graph_duration(unsigned long long duration, struct trace_seq *s, 115print_graph_duration(struct trace_array *tr, unsigned long long duration,
111 u32 flags); 116 struct trace_seq *s, u32 flags);
112 117
113/* Add a function return address to the trace stack on thread info.*/ 118/* Add a function return address to the trace stack on thread info.*/
114int 119int
@@ -653,6 +658,7 @@ static void
653print_graph_irq(struct trace_iterator *iter, unsigned long addr, 658print_graph_irq(struct trace_iterator *iter, unsigned long addr,
654 enum trace_type type, int cpu, pid_t pid, u32 flags) 659 enum trace_type type, int cpu, pid_t pid, u32 flags)
655{ 660{
661 struct trace_array *tr = iter->tr;
656 struct trace_seq *s = &iter->seq; 662 struct trace_seq *s = &iter->seq;
657 struct trace_entry *ent = iter->ent; 663 struct trace_entry *ent = iter->ent;
658 664
@@ -660,7 +666,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
660 addr >= (unsigned long)__irqentry_text_end) 666 addr >= (unsigned long)__irqentry_text_end)
661 return; 667 return;
662 668
663 if (trace_flags & TRACE_ITER_CONTEXT_INFO) { 669 if (tr->trace_flags & TRACE_ITER_CONTEXT_INFO) {
664 /* Absolute time */ 670 /* Absolute time */
665 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) 671 if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
666 print_graph_abs_time(iter->ts, s); 672 print_graph_abs_time(iter->ts, s);
@@ -676,19 +682,19 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
676 } 682 }
677 683
678 /* Latency format */ 684 /* Latency format */
679 if (trace_flags & TRACE_ITER_LATENCY_FMT) 685 if (tr->trace_flags & TRACE_ITER_LATENCY_FMT)
680 print_graph_lat_fmt(s, ent); 686 print_graph_lat_fmt(s, ent);
681 } 687 }
682 688
683 /* No overhead */ 689 /* No overhead */
684 print_graph_duration(0, s, flags | FLAGS_FILL_START); 690 print_graph_duration(tr, 0, s, flags | FLAGS_FILL_START);
685 691
686 if (type == TRACE_GRAPH_ENT) 692 if (type == TRACE_GRAPH_ENT)
687 trace_seq_puts(s, "==========>"); 693 trace_seq_puts(s, "==========>");
688 else 694 else
689 trace_seq_puts(s, "<=========="); 695 trace_seq_puts(s, "<==========");
690 696
691 print_graph_duration(0, s, flags | FLAGS_FILL_END); 697 print_graph_duration(tr, 0, s, flags | FLAGS_FILL_END);
692 trace_seq_putc(s, '\n'); 698 trace_seq_putc(s, '\n');
693} 699}
694 700
@@ -726,11 +732,11 @@ trace_print_graph_duration(unsigned long long duration, struct trace_seq *s)
726} 732}
727 733
728static void 734static void
729print_graph_duration(unsigned long long duration, struct trace_seq *s, 735print_graph_duration(struct trace_array *tr, unsigned long long duration,
730 u32 flags) 736 struct trace_seq *s, u32 flags)
731{ 737{
732 if (!(flags & TRACE_GRAPH_PRINT_DURATION) || 738 if (!(flags & TRACE_GRAPH_PRINT_DURATION) ||
733 !(trace_flags & TRACE_ITER_CONTEXT_INFO)) 739 !(tr->trace_flags & TRACE_ITER_CONTEXT_INFO))
734 return; 740 return;
735 741
736 /* No real adata, just filling the column with spaces */ 742 /* No real adata, just filling the column with spaces */
@@ -764,6 +770,7 @@ print_graph_entry_leaf(struct trace_iterator *iter,
764 struct trace_seq *s, u32 flags) 770 struct trace_seq *s, u32 flags)
765{ 771{
766 struct fgraph_data *data = iter->private; 772 struct fgraph_data *data = iter->private;
773 struct trace_array *tr = iter->tr;
767 struct ftrace_graph_ret *graph_ret; 774 struct ftrace_graph_ret *graph_ret;
768 struct ftrace_graph_ent *call; 775 struct ftrace_graph_ent *call;
769 unsigned long long duration; 776 unsigned long long duration;
@@ -792,7 +799,7 @@ print_graph_entry_leaf(struct trace_iterator *iter,
792 } 799 }
793 800
794 /* Overhead and duration */ 801 /* Overhead and duration */
795 print_graph_duration(duration, s, flags); 802 print_graph_duration(tr, duration, s, flags);
796 803
797 /* Function */ 804 /* Function */
798 for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) 805 for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++)
@@ -810,6 +817,7 @@ print_graph_entry_nested(struct trace_iterator *iter,
810{ 817{
811 struct ftrace_graph_ent *call = &entry->graph_ent; 818 struct ftrace_graph_ent *call = &entry->graph_ent;
812 struct fgraph_data *data = iter->private; 819 struct fgraph_data *data = iter->private;
820 struct trace_array *tr = iter->tr;
813 int i; 821 int i;
814 822
815 if (data) { 823 if (data) {
@@ -825,7 +833,7 @@ print_graph_entry_nested(struct trace_iterator *iter,
825 } 833 }
826 834
827 /* No time */ 835 /* No time */
828 print_graph_duration(0, s, flags | FLAGS_FILL_FULL); 836 print_graph_duration(tr, 0, s, flags | FLAGS_FILL_FULL);
829 837
830 /* Function */ 838 /* Function */
831 for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) 839 for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++)
@@ -849,6 +857,7 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
849{ 857{
850 struct fgraph_data *data = iter->private; 858 struct fgraph_data *data = iter->private;
851 struct trace_entry *ent = iter->ent; 859 struct trace_entry *ent = iter->ent;
860 struct trace_array *tr = iter->tr;
852 int cpu = iter->cpu; 861 int cpu = iter->cpu;
853 862
854 /* Pid */ 863 /* Pid */
@@ -858,7 +867,7 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
858 /* Interrupt */ 867 /* Interrupt */
859 print_graph_irq(iter, addr, type, cpu, ent->pid, flags); 868 print_graph_irq(iter, addr, type, cpu, ent->pid, flags);
860 869
861 if (!(trace_flags & TRACE_ITER_CONTEXT_INFO)) 870 if (!(tr->trace_flags & TRACE_ITER_CONTEXT_INFO))
862 return; 871 return;
863 872
864 /* Absolute time */ 873 /* Absolute time */
@@ -876,7 +885,7 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
876 } 885 }
877 886
878 /* Latency format */ 887 /* Latency format */
879 if (trace_flags & TRACE_ITER_LATENCY_FMT) 888 if (tr->trace_flags & TRACE_ITER_LATENCY_FMT)
880 print_graph_lat_fmt(s, ent); 889 print_graph_lat_fmt(s, ent);
881 890
882 return; 891 return;
@@ -1027,6 +1036,7 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
1027{ 1036{
1028 unsigned long long duration = trace->rettime - trace->calltime; 1037 unsigned long long duration = trace->rettime - trace->calltime;
1029 struct fgraph_data *data = iter->private; 1038 struct fgraph_data *data = iter->private;
1039 struct trace_array *tr = iter->tr;
1030 pid_t pid = ent->pid; 1040 pid_t pid = ent->pid;
1031 int cpu = iter->cpu; 1041 int cpu = iter->cpu;
1032 int func_match = 1; 1042 int func_match = 1;
@@ -1058,7 +1068,7 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
1058 print_graph_prologue(iter, s, 0, 0, flags); 1068 print_graph_prologue(iter, s, 0, 0, flags);
1059 1069
1060 /* Overhead and duration */ 1070 /* Overhead and duration */
1061 print_graph_duration(duration, s, flags); 1071 print_graph_duration(tr, duration, s, flags);
1062 1072
1063 /* Closing brace */ 1073 /* Closing brace */
1064 for (i = 0; i < trace->depth * TRACE_GRAPH_INDENT; i++) 1074 for (i = 0; i < trace->depth * TRACE_GRAPH_INDENT; i++)
@@ -1091,7 +1101,8 @@ static enum print_line_t
1091print_graph_comment(struct trace_seq *s, struct trace_entry *ent, 1101print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
1092 struct trace_iterator *iter, u32 flags) 1102 struct trace_iterator *iter, u32 flags)
1093{ 1103{
1094 unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); 1104 struct trace_array *tr = iter->tr;
1105 unsigned long sym_flags = (tr->trace_flags & TRACE_ITER_SYM_MASK);
1095 struct fgraph_data *data = iter->private; 1106 struct fgraph_data *data = iter->private;
1096 struct trace_event *event; 1107 struct trace_event *event;
1097 int depth = 0; 1108 int depth = 0;
@@ -1104,7 +1115,7 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
1104 print_graph_prologue(iter, s, 0, 0, flags); 1115 print_graph_prologue(iter, s, 0, 0, flags);
1105 1116
1106 /* No time */ 1117 /* No time */
1107 print_graph_duration(0, s, flags | FLAGS_FILL_FULL); 1118 print_graph_duration(tr, 0, s, flags | FLAGS_FILL_FULL);
1108 1119
1109 /* Indentation */ 1120 /* Indentation */
1110 if (depth > 0) 1121 if (depth > 0)
@@ -1245,9 +1256,10 @@ static void print_lat_header(struct seq_file *s, u32 flags)
1245 seq_printf(s, "#%.*s||| / \n", size, spaces); 1256 seq_printf(s, "#%.*s||| / \n", size, spaces);
1246} 1257}
1247 1258
1248static void __print_graph_headers_flags(struct seq_file *s, u32 flags) 1259static void __print_graph_headers_flags(struct trace_array *tr,
1260 struct seq_file *s, u32 flags)
1249{ 1261{
1250 int lat = trace_flags & TRACE_ITER_LATENCY_FMT; 1262 int lat = tr->trace_flags & TRACE_ITER_LATENCY_FMT;
1251 1263
1252 if (lat) 1264 if (lat)
1253 print_lat_header(s, flags); 1265 print_lat_header(s, flags);
@@ -1289,11 +1301,12 @@ static void print_graph_headers(struct seq_file *s)
1289void print_graph_headers_flags(struct seq_file *s, u32 flags) 1301void print_graph_headers_flags(struct seq_file *s, u32 flags)
1290{ 1302{
1291 struct trace_iterator *iter = s->private; 1303 struct trace_iterator *iter = s->private;
1304 struct trace_array *tr = iter->tr;
1292 1305
1293 if (!(trace_flags & TRACE_ITER_CONTEXT_INFO)) 1306 if (!(tr->trace_flags & TRACE_ITER_CONTEXT_INFO))
1294 return; 1307 return;
1295 1308
1296 if (trace_flags & TRACE_ITER_LATENCY_FMT) { 1309 if (tr->trace_flags & TRACE_ITER_LATENCY_FMT) {
1297 /* print nothing if the buffers are empty */ 1310 /* print nothing if the buffers are empty */
1298 if (trace_empty(iter)) 1311 if (trace_empty(iter))
1299 return; 1312 return;
@@ -1301,7 +1314,7 @@ void print_graph_headers_flags(struct seq_file *s, u32 flags)
1301 print_trace_header(s, iter); 1314 print_trace_header(s, iter);
1302 } 1315 }
1303 1316
1304 __print_graph_headers_flags(s, flags); 1317 __print_graph_headers_flags(tr, s, flags);
1305} 1318}
1306 1319
1307void graph_trace_open(struct trace_iterator *iter) 1320void graph_trace_open(struct trace_iterator *iter)
@@ -1362,6 +1375,12 @@ func_graph_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)
1362 if (bit == TRACE_GRAPH_PRINT_IRQS) 1375 if (bit == TRACE_GRAPH_PRINT_IRQS)
1363 ftrace_graph_skip_irqs = !set; 1376 ftrace_graph_skip_irqs = !set;
1364 1377
1378 if (bit == TRACE_GRAPH_SLEEP_TIME)
1379 ftrace_graph_sleep_time_control(set);
1380
1381 if (bit == TRACE_GRAPH_GRAPH_TIME)
1382 ftrace_graph_graph_time_control(set);
1383
1365 return 0; 1384 return 0;
1366} 1385}
1367 1386