diff options
Diffstat (limited to 'kernel/trace/trace_functions_graph.c')
| -rw-r--r-- | kernel/trace/trace_functions_graph.c | 63 |
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 | ||
| 89 | static struct tracer_flags tracer_flags = { | 93 | static 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 | ||
| 109 | static void | 114 | static void |
| 110 | print_graph_duration(unsigned long long duration, struct trace_seq *s, | 115 | print_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.*/ |
| 114 | int | 119 | int |
| @@ -653,6 +658,7 @@ static void | |||
| 653 | print_graph_irq(struct trace_iterator *iter, unsigned long addr, | 658 | print_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 | ||
| 728 | static void | 734 | static void |
| 729 | print_graph_duration(unsigned long long duration, struct trace_seq *s, | 735 | print_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 | |||
| 1091 | print_graph_comment(struct trace_seq *s, struct trace_entry *ent, | 1101 | print_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 | ||
| 1248 | static void __print_graph_headers_flags(struct seq_file *s, u32 flags) | 1259 | static 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) | |||
| 1289 | void print_graph_headers_flags(struct seq_file *s, u32 flags) | 1301 | void 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 | ||
| 1307 | void graph_trace_open(struct trace_iterator *iter) | 1320 | void 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 | ||
