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.c164
1 files changed, 105 insertions, 59 deletions
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 669b9c31861d..dd11c830eb84 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -40,7 +40,7 @@ struct fgraph_data {
40#define TRACE_GRAPH_PRINT_OVERHEAD 0x4 40#define TRACE_GRAPH_PRINT_OVERHEAD 0x4
41#define TRACE_GRAPH_PRINT_PROC 0x8 41#define TRACE_GRAPH_PRINT_PROC 0x8
42#define TRACE_GRAPH_PRINT_DURATION 0x10 42#define TRACE_GRAPH_PRINT_DURATION 0x10
43#define TRACE_GRAPH_PRINT_ABS_TIME 0X20 43#define TRACE_GRAPH_PRINT_ABS_TIME 0x20
44 44
45static struct tracer_opt trace_opts[] = { 45static struct tracer_opt trace_opts[] = {
46 /* Display overruns? (for self-debug purpose) */ 46 /* Display overruns? (for self-debug purpose) */
@@ -179,7 +179,7 @@ unsigned long ftrace_return_to_handler(unsigned long frame_pointer)
179 return ret; 179 return ret;
180} 180}
181 181
182static int __trace_graph_entry(struct trace_array *tr, 182int __trace_graph_entry(struct trace_array *tr,
183 struct ftrace_graph_ent *trace, 183 struct ftrace_graph_ent *trace,
184 unsigned long flags, 184 unsigned long flags,
185 int pc) 185 int pc)
@@ -246,7 +246,7 @@ int trace_graph_thresh_entry(struct ftrace_graph_ent *trace)
246 return trace_graph_entry(trace); 246 return trace_graph_entry(trace);
247} 247}
248 248
249static void __trace_graph_return(struct trace_array *tr, 249void __trace_graph_return(struct trace_array *tr,
250 struct ftrace_graph_ret *trace, 250 struct ftrace_graph_ret *trace,
251 unsigned long flags, 251 unsigned long flags,
252 int pc) 252 int pc)
@@ -527,17 +527,18 @@ get_return_for_leaf(struct trace_iterator *iter,
527 527
528/* Signal a overhead of time execution to the output */ 528/* Signal a overhead of time execution to the output */
529static int 529static int
530print_graph_overhead(unsigned long long duration, struct trace_seq *s) 530print_graph_overhead(unsigned long long duration, struct trace_seq *s,
531 u32 flags)
531{ 532{
532 /* If duration disappear, we don't need anything */ 533 /* If duration disappear, we don't need anything */
533 if (!(tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)) 534 if (!(flags & TRACE_GRAPH_PRINT_DURATION))
534 return 1; 535 return 1;
535 536
536 /* Non nested entry or return */ 537 /* Non nested entry or return */
537 if (duration == -1) 538 if (duration == -1)
538 return trace_seq_printf(s, " "); 539 return trace_seq_printf(s, " ");
539 540
540 if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) { 541 if (flags & TRACE_GRAPH_PRINT_OVERHEAD) {
541 /* Duration exceeded 100 msecs */ 542 /* Duration exceeded 100 msecs */
542 if (duration > 100000ULL) 543 if (duration > 100000ULL)
543 return trace_seq_printf(s, "! "); 544 return trace_seq_printf(s, "! ");
@@ -563,7 +564,7 @@ static int print_graph_abs_time(u64 t, struct trace_seq *s)
563 564
564static enum print_line_t 565static enum print_line_t
565print_graph_irq(struct trace_iterator *iter, unsigned long addr, 566print_graph_irq(struct trace_iterator *iter, unsigned long addr,
566 enum trace_type type, int cpu, pid_t pid) 567 enum trace_type type, int cpu, pid_t pid, u32 flags)
567{ 568{
568 int ret; 569 int ret;
569 struct trace_seq *s = &iter->seq; 570 struct trace_seq *s = &iter->seq;
@@ -573,21 +574,21 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
573 return TRACE_TYPE_UNHANDLED; 574 return TRACE_TYPE_UNHANDLED;
574 575
575 /* Absolute time */ 576 /* Absolute time */
576 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) { 577 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) {
577 ret = print_graph_abs_time(iter->ts, s); 578 ret = print_graph_abs_time(iter->ts, s);
578 if (!ret) 579 if (!ret)
579 return TRACE_TYPE_PARTIAL_LINE; 580 return TRACE_TYPE_PARTIAL_LINE;
580 } 581 }
581 582
582 /* Cpu */ 583 /* Cpu */
583 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) { 584 if (flags & TRACE_GRAPH_PRINT_CPU) {
584 ret = print_graph_cpu(s, cpu); 585 ret = print_graph_cpu(s, cpu);
585 if (ret == TRACE_TYPE_PARTIAL_LINE) 586 if (ret == TRACE_TYPE_PARTIAL_LINE)
586 return TRACE_TYPE_PARTIAL_LINE; 587 return TRACE_TYPE_PARTIAL_LINE;
587 } 588 }
588 589
589 /* Proc */ 590 /* Proc */
590 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) { 591 if (flags & TRACE_GRAPH_PRINT_PROC) {
591 ret = print_graph_proc(s, pid); 592 ret = print_graph_proc(s, pid);
592 if (ret == TRACE_TYPE_PARTIAL_LINE) 593 if (ret == TRACE_TYPE_PARTIAL_LINE)
593 return TRACE_TYPE_PARTIAL_LINE; 594 return TRACE_TYPE_PARTIAL_LINE;
@@ -597,7 +598,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
597 } 598 }
598 599
599 /* No overhead */ 600 /* No overhead */
600 ret = print_graph_overhead(-1, s); 601 ret = print_graph_overhead(-1, s, flags);
601 if (!ret) 602 if (!ret)
602 return TRACE_TYPE_PARTIAL_LINE; 603 return TRACE_TYPE_PARTIAL_LINE;
603 604
@@ -610,7 +611,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
610 return TRACE_TYPE_PARTIAL_LINE; 611 return TRACE_TYPE_PARTIAL_LINE;
611 612
612 /* Don't close the duration column if haven't one */ 613 /* Don't close the duration column if haven't one */
613 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 614 if (flags & TRACE_GRAPH_PRINT_DURATION)
614 trace_seq_printf(s, " |"); 615 trace_seq_printf(s, " |");
615 ret = trace_seq_printf(s, "\n"); 616 ret = trace_seq_printf(s, "\n");
616 617
@@ -680,7 +681,8 @@ print_graph_duration(unsigned long long duration, struct trace_seq *s)
680static enum print_line_t 681static enum print_line_t
681print_graph_entry_leaf(struct trace_iterator *iter, 682print_graph_entry_leaf(struct trace_iterator *iter,
682 struct ftrace_graph_ent_entry *entry, 683 struct ftrace_graph_ent_entry *entry,
683 struct ftrace_graph_ret_entry *ret_entry, struct trace_seq *s) 684 struct ftrace_graph_ret_entry *ret_entry,
685 struct trace_seq *s, u32 flags)
684{ 686{
685 struct fgraph_data *data = iter->private; 687 struct fgraph_data *data = iter->private;
686 struct ftrace_graph_ret *graph_ret; 688 struct ftrace_graph_ret *graph_ret;
@@ -712,12 +714,12 @@ print_graph_entry_leaf(struct trace_iterator *iter,
712 } 714 }
713 715
714 /* Overhead */ 716 /* Overhead */
715 ret = print_graph_overhead(duration, s); 717 ret = print_graph_overhead(duration, s, flags);
716 if (!ret) 718 if (!ret)
717 return TRACE_TYPE_PARTIAL_LINE; 719 return TRACE_TYPE_PARTIAL_LINE;
718 720
719 /* Duration */ 721 /* Duration */
720 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) { 722 if (flags & TRACE_GRAPH_PRINT_DURATION) {
721 ret = print_graph_duration(duration, s); 723 ret = print_graph_duration(duration, s);
722 if (ret == TRACE_TYPE_PARTIAL_LINE) 724 if (ret == TRACE_TYPE_PARTIAL_LINE)
723 return TRACE_TYPE_PARTIAL_LINE; 725 return TRACE_TYPE_PARTIAL_LINE;
@@ -740,7 +742,7 @@ print_graph_entry_leaf(struct trace_iterator *iter,
740static enum print_line_t 742static enum print_line_t
741print_graph_entry_nested(struct trace_iterator *iter, 743print_graph_entry_nested(struct trace_iterator *iter,
742 struct ftrace_graph_ent_entry *entry, 744 struct ftrace_graph_ent_entry *entry,
743 struct trace_seq *s, int cpu) 745 struct trace_seq *s, int cpu, u32 flags)
744{ 746{
745 struct ftrace_graph_ent *call = &entry->graph_ent; 747 struct ftrace_graph_ent *call = &entry->graph_ent;
746 struct fgraph_data *data = iter->private; 748 struct fgraph_data *data = iter->private;
@@ -760,12 +762,12 @@ print_graph_entry_nested(struct trace_iterator *iter,
760 } 762 }
761 763
762 /* No overhead */ 764 /* No overhead */
763 ret = print_graph_overhead(-1, s); 765 ret = print_graph_overhead(-1, s, flags);
764 if (!ret) 766 if (!ret)
765 return TRACE_TYPE_PARTIAL_LINE; 767 return TRACE_TYPE_PARTIAL_LINE;
766 768
767 /* No time */ 769 /* No time */
768 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) { 770 if (flags & TRACE_GRAPH_PRINT_DURATION) {
769 ret = trace_seq_printf(s, " | "); 771 ret = trace_seq_printf(s, " | ");
770 if (!ret) 772 if (!ret)
771 return TRACE_TYPE_PARTIAL_LINE; 773 return TRACE_TYPE_PARTIAL_LINE;
@@ -791,7 +793,7 @@ print_graph_entry_nested(struct trace_iterator *iter,
791 793
792static enum print_line_t 794static enum print_line_t
793print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s, 795print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
794 int type, unsigned long addr) 796 int type, unsigned long addr, u32 flags)
795{ 797{
796 struct fgraph_data *data = iter->private; 798 struct fgraph_data *data = iter->private;
797 struct trace_entry *ent = iter->ent; 799 struct trace_entry *ent = iter->ent;
@@ -804,27 +806,27 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
804 806
805 if (type) { 807 if (type) {
806 /* Interrupt */ 808 /* Interrupt */
807 ret = print_graph_irq(iter, addr, type, cpu, ent->pid); 809 ret = print_graph_irq(iter, addr, type, cpu, ent->pid, flags);
808 if (ret == TRACE_TYPE_PARTIAL_LINE) 810 if (ret == TRACE_TYPE_PARTIAL_LINE)
809 return TRACE_TYPE_PARTIAL_LINE; 811 return TRACE_TYPE_PARTIAL_LINE;
810 } 812 }
811 813
812 /* Absolute time */ 814 /* Absolute time */
813 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) { 815 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) {
814 ret = print_graph_abs_time(iter->ts, s); 816 ret = print_graph_abs_time(iter->ts, s);
815 if (!ret) 817 if (!ret)
816 return TRACE_TYPE_PARTIAL_LINE; 818 return TRACE_TYPE_PARTIAL_LINE;
817 } 819 }
818 820
819 /* Cpu */ 821 /* Cpu */
820 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) { 822 if (flags & TRACE_GRAPH_PRINT_CPU) {
821 ret = print_graph_cpu(s, cpu); 823 ret = print_graph_cpu(s, cpu);
822 if (ret == TRACE_TYPE_PARTIAL_LINE) 824 if (ret == TRACE_TYPE_PARTIAL_LINE)
823 return TRACE_TYPE_PARTIAL_LINE; 825 return TRACE_TYPE_PARTIAL_LINE;
824 } 826 }
825 827
826 /* Proc */ 828 /* Proc */
827 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) { 829 if (flags & TRACE_GRAPH_PRINT_PROC) {
828 ret = print_graph_proc(s, ent->pid); 830 ret = print_graph_proc(s, ent->pid);
829 if (ret == TRACE_TYPE_PARTIAL_LINE) 831 if (ret == TRACE_TYPE_PARTIAL_LINE)
830 return TRACE_TYPE_PARTIAL_LINE; 832 return TRACE_TYPE_PARTIAL_LINE;
@@ -846,7 +848,7 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
846 848
847static enum print_line_t 849static enum print_line_t
848print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s, 850print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
849 struct trace_iterator *iter) 851 struct trace_iterator *iter, u32 flags)
850{ 852{
851 struct fgraph_data *data = iter->private; 853 struct fgraph_data *data = iter->private;
852 struct ftrace_graph_ent *call = &field->graph_ent; 854 struct ftrace_graph_ent *call = &field->graph_ent;
@@ -854,14 +856,14 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
854 static enum print_line_t ret; 856 static enum print_line_t ret;
855 int cpu = iter->cpu; 857 int cpu = iter->cpu;
856 858
857 if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func)) 859 if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func, flags))
858 return TRACE_TYPE_PARTIAL_LINE; 860 return TRACE_TYPE_PARTIAL_LINE;
859 861
860 leaf_ret = get_return_for_leaf(iter, field); 862 leaf_ret = get_return_for_leaf(iter, field);
861 if (leaf_ret) 863 if (leaf_ret)
862 ret = print_graph_entry_leaf(iter, field, leaf_ret, s); 864 ret = print_graph_entry_leaf(iter, field, leaf_ret, s, flags);
863 else 865 else
864 ret = print_graph_entry_nested(iter, field, s, cpu); 866 ret = print_graph_entry_nested(iter, field, s, cpu, flags);
865 867
866 if (data) { 868 if (data) {
867 /* 869 /*
@@ -880,7 +882,8 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
880 882
881static enum print_line_t 883static enum print_line_t
882print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, 884print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
883 struct trace_entry *ent, struct trace_iterator *iter) 885 struct trace_entry *ent, struct trace_iterator *iter,
886 u32 flags)
884{ 887{
885 unsigned long long duration = trace->rettime - trace->calltime; 888 unsigned long long duration = trace->rettime - trace->calltime;
886 struct fgraph_data *data = iter->private; 889 struct fgraph_data *data = iter->private;
@@ -910,16 +913,16 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
910 } 913 }
911 } 914 }
912 915
913 if (print_graph_prologue(iter, s, 0, 0)) 916 if (print_graph_prologue(iter, s, 0, 0, flags))
914 return TRACE_TYPE_PARTIAL_LINE; 917 return TRACE_TYPE_PARTIAL_LINE;
915 918
916 /* Overhead */ 919 /* Overhead */
917 ret = print_graph_overhead(duration, s); 920 ret = print_graph_overhead(duration, s, flags);
918 if (!ret) 921 if (!ret)
919 return TRACE_TYPE_PARTIAL_LINE; 922 return TRACE_TYPE_PARTIAL_LINE;
920 923
921 /* Duration */ 924 /* Duration */
922 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) { 925 if (flags & TRACE_GRAPH_PRINT_DURATION) {
923 ret = print_graph_duration(duration, s); 926 ret = print_graph_duration(duration, s);
924 if (ret == TRACE_TYPE_PARTIAL_LINE) 927 if (ret == TRACE_TYPE_PARTIAL_LINE)
925 return TRACE_TYPE_PARTIAL_LINE; 928 return TRACE_TYPE_PARTIAL_LINE;
@@ -949,14 +952,15 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
949 } 952 }
950 953
951 /* Overrun */ 954 /* Overrun */
952 if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERRUN) { 955 if (flags & TRACE_GRAPH_PRINT_OVERRUN) {
953 ret = trace_seq_printf(s, " (Overruns: %lu)\n", 956 ret = trace_seq_printf(s, " (Overruns: %lu)\n",
954 trace->overrun); 957 trace->overrun);
955 if (!ret) 958 if (!ret)
956 return TRACE_TYPE_PARTIAL_LINE; 959 return TRACE_TYPE_PARTIAL_LINE;
957 } 960 }
958 961
959 ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET, cpu, pid); 962 ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET,
963 cpu, pid, flags);
960 if (ret == TRACE_TYPE_PARTIAL_LINE) 964 if (ret == TRACE_TYPE_PARTIAL_LINE)
961 return TRACE_TYPE_PARTIAL_LINE; 965 return TRACE_TYPE_PARTIAL_LINE;
962 966
@@ -964,8 +968,8 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
964} 968}
965 969
966static enum print_line_t 970static enum print_line_t
967print_graph_comment(struct trace_seq *s, struct trace_entry *ent, 971print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
968 struct trace_iterator *iter) 972 struct trace_iterator *iter, u32 flags)
969{ 973{
970 unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); 974 unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
971 struct fgraph_data *data = iter->private; 975 struct fgraph_data *data = iter->private;
@@ -977,16 +981,16 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
977 if (data) 981 if (data)
978 depth = per_cpu_ptr(data->cpu_data, iter->cpu)->depth; 982 depth = per_cpu_ptr(data->cpu_data, iter->cpu)->depth;
979 983
980 if (print_graph_prologue(iter, s, 0, 0)) 984 if (print_graph_prologue(iter, s, 0, 0, flags))
981 return TRACE_TYPE_PARTIAL_LINE; 985 return TRACE_TYPE_PARTIAL_LINE;
982 986
983 /* No overhead */ 987 /* No overhead */
984 ret = print_graph_overhead(-1, s); 988 ret = print_graph_overhead(-1, s, flags);
985 if (!ret) 989 if (!ret)
986 return TRACE_TYPE_PARTIAL_LINE; 990 return TRACE_TYPE_PARTIAL_LINE;
987 991
988 /* No time */ 992 /* No time */
989 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) { 993 if (flags & TRACE_GRAPH_PRINT_DURATION) {
990 ret = trace_seq_printf(s, " | "); 994 ret = trace_seq_printf(s, " | ");
991 if (!ret) 995 if (!ret)
992 return TRACE_TYPE_PARTIAL_LINE; 996 return TRACE_TYPE_PARTIAL_LINE;
@@ -1041,7 +1045,7 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
1041 1045
1042 1046
1043enum print_line_t 1047enum print_line_t
1044print_graph_function(struct trace_iterator *iter) 1048print_graph_function_flags(struct trace_iterator *iter, u32 flags)
1045{ 1049{
1046 struct ftrace_graph_ent_entry *field; 1050 struct ftrace_graph_ent_entry *field;
1047 struct fgraph_data *data = iter->private; 1051 struct fgraph_data *data = iter->private;
@@ -1062,7 +1066,7 @@ print_graph_function(struct trace_iterator *iter)
1062 if (data && data->failed) { 1066 if (data && data->failed) {
1063 field = &data->ent; 1067 field = &data->ent;
1064 iter->cpu = data->cpu; 1068 iter->cpu = data->cpu;
1065 ret = print_graph_entry(field, s, iter); 1069 ret = print_graph_entry(field, s, iter, flags);
1066 if (ret == TRACE_TYPE_HANDLED && iter->cpu != cpu) { 1070 if (ret == TRACE_TYPE_HANDLED && iter->cpu != cpu) {
1067 per_cpu_ptr(data->cpu_data, iter->cpu)->ignore = 1; 1071 per_cpu_ptr(data->cpu_data, iter->cpu)->ignore = 1;
1068 ret = TRACE_TYPE_NO_CONSUME; 1072 ret = TRACE_TYPE_NO_CONSUME;
@@ -1082,32 +1086,49 @@ print_graph_function(struct trace_iterator *iter)
1082 struct ftrace_graph_ent_entry saved; 1086 struct ftrace_graph_ent_entry saved;
1083 trace_assign_type(field, entry); 1087 trace_assign_type(field, entry);
1084 saved = *field; 1088 saved = *field;
1085 return print_graph_entry(&saved, s, iter); 1089 return print_graph_entry(&saved, s, iter, flags);
1086 } 1090 }
1087 case TRACE_GRAPH_RET: { 1091 case TRACE_GRAPH_RET: {
1088 struct ftrace_graph_ret_entry *field; 1092 struct ftrace_graph_ret_entry *field;
1089 trace_assign_type(field, entry); 1093 trace_assign_type(field, entry);
1090 return print_graph_return(&field->ret, s, entry, iter); 1094 return print_graph_return(&field->ret, s, entry, iter, flags);
1091 } 1095 }
1096 case TRACE_STACK:
1097 case TRACE_FN:
1098 /* dont trace stack and functions as comments */
1099 return TRACE_TYPE_UNHANDLED;
1100
1092 default: 1101 default:
1093 return print_graph_comment(s, entry, iter); 1102 return print_graph_comment(s, entry, iter, flags);
1094 } 1103 }
1095 1104
1096 return TRACE_TYPE_HANDLED; 1105 return TRACE_TYPE_HANDLED;
1097} 1106}
1098 1107
1099static void print_lat_header(struct seq_file *s) 1108static enum print_line_t
1109print_graph_function(struct trace_iterator *iter)
1110{
1111 return print_graph_function_flags(iter, tracer_flags.val);
1112}
1113
1114static enum print_line_t
1115print_graph_function_event(struct trace_iterator *iter, int flags)
1116{
1117 return print_graph_function(iter);
1118}
1119
1120static void print_lat_header(struct seq_file *s, u32 flags)
1100{ 1121{
1101 static const char spaces[] = " " /* 16 spaces */ 1122 static const char spaces[] = " " /* 16 spaces */
1102 " " /* 4 spaces */ 1123 " " /* 4 spaces */
1103 " "; /* 17 spaces */ 1124 " "; /* 17 spaces */
1104 int size = 0; 1125 int size = 0;
1105 1126
1106 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) 1127 if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
1107 size += 16; 1128 size += 16;
1108 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) 1129 if (flags & TRACE_GRAPH_PRINT_CPU)
1109 size += 4; 1130 size += 4;
1110 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1131 if (flags & TRACE_GRAPH_PRINT_PROC)
1111 size += 17; 1132 size += 17;
1112 1133
1113 seq_printf(s, "#%.*s _-----=> irqs-off \n", size, spaces); 1134 seq_printf(s, "#%.*s _-----=> irqs-off \n", size, spaces);
@@ -1118,43 +1139,48 @@ static void print_lat_header(struct seq_file *s)
1118 seq_printf(s, "#%.*s|||| / \n", size, spaces); 1139 seq_printf(s, "#%.*s|||| / \n", size, spaces);
1119} 1140}
1120 1141
1121static void print_graph_headers(struct seq_file *s) 1142void print_graph_headers_flags(struct seq_file *s, u32 flags)
1122{ 1143{
1123 int lat = trace_flags & TRACE_ITER_LATENCY_FMT; 1144 int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
1124 1145
1125 if (lat) 1146 if (lat)
1126 print_lat_header(s); 1147 print_lat_header(s, flags);
1127 1148
1128 /* 1st line */ 1149 /* 1st line */
1129 seq_printf(s, "#"); 1150 seq_printf(s, "#");
1130 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) 1151 if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
1131 seq_printf(s, " TIME "); 1152 seq_printf(s, " TIME ");
1132 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) 1153 if (flags & TRACE_GRAPH_PRINT_CPU)
1133 seq_printf(s, " CPU"); 1154 seq_printf(s, " CPU");
1134 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1155 if (flags & TRACE_GRAPH_PRINT_PROC)
1135 seq_printf(s, " TASK/PID "); 1156 seq_printf(s, " TASK/PID ");
1136 if (lat) 1157 if (lat)
1137 seq_printf(s, "|||||"); 1158 seq_printf(s, "|||||");
1138 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 1159 if (flags & TRACE_GRAPH_PRINT_DURATION)
1139 seq_printf(s, " DURATION "); 1160 seq_printf(s, " DURATION ");
1140 seq_printf(s, " FUNCTION CALLS\n"); 1161 seq_printf(s, " FUNCTION CALLS\n");
1141 1162
1142 /* 2nd line */ 1163 /* 2nd line */
1143 seq_printf(s, "#"); 1164 seq_printf(s, "#");
1144 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) 1165 if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
1145 seq_printf(s, " | "); 1166 seq_printf(s, " | ");
1146 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) 1167 if (flags & TRACE_GRAPH_PRINT_CPU)
1147 seq_printf(s, " | "); 1168 seq_printf(s, " | ");
1148 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1169 if (flags & TRACE_GRAPH_PRINT_PROC)
1149 seq_printf(s, " | | "); 1170 seq_printf(s, " | | ");
1150 if (lat) 1171 if (lat)
1151 seq_printf(s, "|||||"); 1172 seq_printf(s, "|||||");
1152 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 1173 if (flags & TRACE_GRAPH_PRINT_DURATION)
1153 seq_printf(s, " | | "); 1174 seq_printf(s, " | | ");
1154 seq_printf(s, " | | | |\n"); 1175 seq_printf(s, " | | | |\n");
1155} 1176}
1156 1177
1157static void graph_trace_open(struct trace_iterator *iter) 1178void print_graph_headers(struct seq_file *s)
1179{
1180 print_graph_headers_flags(s, tracer_flags.val);
1181}
1182
1183void graph_trace_open(struct trace_iterator *iter)
1158{ 1184{
1159 /* pid and depth on the last trace processed */ 1185 /* pid and depth on the last trace processed */
1160 struct fgraph_data *data; 1186 struct fgraph_data *data;
@@ -1189,7 +1215,7 @@ static void graph_trace_open(struct trace_iterator *iter)
1189 pr_warning("function graph tracer: not enough memory\n"); 1215 pr_warning("function graph tracer: not enough memory\n");
1190} 1216}
1191 1217
1192static void graph_trace_close(struct trace_iterator *iter) 1218void graph_trace_close(struct trace_iterator *iter)
1193{ 1219{
1194 struct fgraph_data *data = iter->private; 1220 struct fgraph_data *data = iter->private;
1195 1221
@@ -1199,6 +1225,16 @@ static void graph_trace_close(struct trace_iterator *iter)
1199 } 1225 }
1200} 1226}
1201 1227
1228static struct trace_event graph_trace_entry_event = {
1229 .type = TRACE_GRAPH_ENT,
1230 .trace = print_graph_function_event,
1231};
1232
1233static struct trace_event graph_trace_ret_event = {
1234 .type = TRACE_GRAPH_RET,
1235 .trace = print_graph_function_event,
1236};
1237
1202static struct tracer graph_trace __read_mostly = { 1238static struct tracer graph_trace __read_mostly = {
1203 .name = "function_graph", 1239 .name = "function_graph",
1204 .open = graph_trace_open, 1240 .open = graph_trace_open,
@@ -1220,6 +1256,16 @@ static __init int init_graph_trace(void)
1220{ 1256{
1221 max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1); 1257 max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1);
1222 1258
1259 if (!register_ftrace_event(&graph_trace_entry_event)) {
1260 pr_warning("Warning: could not register graph trace events\n");
1261 return 1;
1262 }
1263
1264 if (!register_ftrace_event(&graph_trace_ret_event)) {
1265 pr_warning("Warning: could not register graph trace events\n");
1266 return 1;
1267 }
1268
1223 return register_tracer(&graph_trace); 1269 return register_tracer(&graph_trace);
1224} 1270}
1225 1271