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.c179
1 files changed, 116 insertions, 63 deletions
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 9aed1a5cf553..6bff23625781 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)
@@ -490,9 +490,10 @@ get_return_for_leaf(struct trace_iterator *iter,
490 * We need to consume the current entry to see 490 * We need to consume the current entry to see
491 * the next one. 491 * the next one.
492 */ 492 */
493 ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL); 493 ring_buffer_consume(iter->tr->buffer, iter->cpu,
494 NULL, NULL);
494 event = ring_buffer_peek(iter->tr->buffer, iter->cpu, 495 event = ring_buffer_peek(iter->tr->buffer, iter->cpu,
495 NULL); 496 NULL, NULL);
496 } 497 }
497 498
498 if (!event) 499 if (!event)
@@ -526,17 +527,18 @@ get_return_for_leaf(struct trace_iterator *iter,
526 527
527/* Signal a overhead of time execution to the output */ 528/* Signal a overhead of time execution to the output */
528static int 529static int
529print_graph_overhead(unsigned long long duration, struct trace_seq *s) 530print_graph_overhead(unsigned long long duration, struct trace_seq *s,
531 u32 flags)
530{ 532{
531 /* If duration disappear, we don't need anything */ 533 /* If duration disappear, we don't need anything */
532 if (!(tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)) 534 if (!(flags & TRACE_GRAPH_PRINT_DURATION))
533 return 1; 535 return 1;
534 536
535 /* Non nested entry or return */ 537 /* Non nested entry or return */
536 if (duration == -1) 538 if (duration == -1)
537 return trace_seq_printf(s, " "); 539 return trace_seq_printf(s, " ");
538 540
539 if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) { 541 if (flags & TRACE_GRAPH_PRINT_OVERHEAD) {
540 /* Duration exceeded 100 msecs */ 542 /* Duration exceeded 100 msecs */
541 if (duration > 100000ULL) 543 if (duration > 100000ULL)
542 return trace_seq_printf(s, "! "); 544 return trace_seq_printf(s, "! ");
@@ -562,7 +564,7 @@ static int print_graph_abs_time(u64 t, struct trace_seq *s)
562 564
563static enum print_line_t 565static enum print_line_t
564print_graph_irq(struct trace_iterator *iter, unsigned long addr, 566print_graph_irq(struct trace_iterator *iter, unsigned long addr,
565 enum trace_type type, int cpu, pid_t pid) 567 enum trace_type type, int cpu, pid_t pid, u32 flags)
566{ 568{
567 int ret; 569 int ret;
568 struct trace_seq *s = &iter->seq; 570 struct trace_seq *s = &iter->seq;
@@ -572,21 +574,21 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
572 return TRACE_TYPE_UNHANDLED; 574 return TRACE_TYPE_UNHANDLED;
573 575
574 /* Absolute time */ 576 /* Absolute time */
575 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) { 577 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) {
576 ret = print_graph_abs_time(iter->ts, s); 578 ret = print_graph_abs_time(iter->ts, s);
577 if (!ret) 579 if (!ret)
578 return TRACE_TYPE_PARTIAL_LINE; 580 return TRACE_TYPE_PARTIAL_LINE;
579 } 581 }
580 582
581 /* Cpu */ 583 /* Cpu */
582 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) { 584 if (flags & TRACE_GRAPH_PRINT_CPU) {
583 ret = print_graph_cpu(s, cpu); 585 ret = print_graph_cpu(s, cpu);
584 if (ret == TRACE_TYPE_PARTIAL_LINE) 586 if (ret == TRACE_TYPE_PARTIAL_LINE)
585 return TRACE_TYPE_PARTIAL_LINE; 587 return TRACE_TYPE_PARTIAL_LINE;
586 } 588 }
587 589
588 /* Proc */ 590 /* Proc */
589 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) { 591 if (flags & TRACE_GRAPH_PRINT_PROC) {
590 ret = print_graph_proc(s, pid); 592 ret = print_graph_proc(s, pid);
591 if (ret == TRACE_TYPE_PARTIAL_LINE) 593 if (ret == TRACE_TYPE_PARTIAL_LINE)
592 return TRACE_TYPE_PARTIAL_LINE; 594 return TRACE_TYPE_PARTIAL_LINE;
@@ -596,7 +598,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
596 } 598 }
597 599
598 /* No overhead */ 600 /* No overhead */
599 ret = print_graph_overhead(-1, s); 601 ret = print_graph_overhead(-1, s, flags);
600 if (!ret) 602 if (!ret)
601 return TRACE_TYPE_PARTIAL_LINE; 603 return TRACE_TYPE_PARTIAL_LINE;
602 604
@@ -609,7 +611,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
609 return TRACE_TYPE_PARTIAL_LINE; 611 return TRACE_TYPE_PARTIAL_LINE;
610 612
611 /* Don't close the duration column if haven't one */ 613 /* Don't close the duration column if haven't one */
612 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 614 if (flags & TRACE_GRAPH_PRINT_DURATION)
613 trace_seq_printf(s, " |"); 615 trace_seq_printf(s, " |");
614 ret = trace_seq_printf(s, "\n"); 616 ret = trace_seq_printf(s, "\n");
615 617
@@ -639,7 +641,8 @@ trace_print_graph_duration(unsigned long long duration, struct trace_seq *s)
639 641
640 /* Print nsecs (we don't want to exceed 7 numbers) */ 642 /* Print nsecs (we don't want to exceed 7 numbers) */
641 if (len < 7) { 643 if (len < 7) {
642 snprintf(nsecs_str, 8 - len, "%03lu", nsecs_rem); 644 snprintf(nsecs_str, min(sizeof(nsecs_str), 8UL - len), "%03lu",
645 nsecs_rem);
643 ret = trace_seq_printf(s, ".%s", nsecs_str); 646 ret = trace_seq_printf(s, ".%s", nsecs_str);
644 if (!ret) 647 if (!ret)
645 return TRACE_TYPE_PARTIAL_LINE; 648 return TRACE_TYPE_PARTIAL_LINE;
@@ -679,7 +682,8 @@ print_graph_duration(unsigned long long duration, struct trace_seq *s)
679static enum print_line_t 682static enum print_line_t
680print_graph_entry_leaf(struct trace_iterator *iter, 683print_graph_entry_leaf(struct trace_iterator *iter,
681 struct ftrace_graph_ent_entry *entry, 684 struct ftrace_graph_ent_entry *entry,
682 struct ftrace_graph_ret_entry *ret_entry, struct trace_seq *s) 685 struct ftrace_graph_ret_entry *ret_entry,
686 struct trace_seq *s, u32 flags)
683{ 687{
684 struct fgraph_data *data = iter->private; 688 struct fgraph_data *data = iter->private;
685 struct ftrace_graph_ret *graph_ret; 689 struct ftrace_graph_ret *graph_ret;
@@ -711,12 +715,12 @@ print_graph_entry_leaf(struct trace_iterator *iter,
711 } 715 }
712 716
713 /* Overhead */ 717 /* Overhead */
714 ret = print_graph_overhead(duration, s); 718 ret = print_graph_overhead(duration, s, flags);
715 if (!ret) 719 if (!ret)
716 return TRACE_TYPE_PARTIAL_LINE; 720 return TRACE_TYPE_PARTIAL_LINE;
717 721
718 /* Duration */ 722 /* Duration */
719 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) { 723 if (flags & TRACE_GRAPH_PRINT_DURATION) {
720 ret = print_graph_duration(duration, s); 724 ret = print_graph_duration(duration, s);
721 if (ret == TRACE_TYPE_PARTIAL_LINE) 725 if (ret == TRACE_TYPE_PARTIAL_LINE)
722 return TRACE_TYPE_PARTIAL_LINE; 726 return TRACE_TYPE_PARTIAL_LINE;
@@ -739,7 +743,7 @@ print_graph_entry_leaf(struct trace_iterator *iter,
739static enum print_line_t 743static enum print_line_t
740print_graph_entry_nested(struct trace_iterator *iter, 744print_graph_entry_nested(struct trace_iterator *iter,
741 struct ftrace_graph_ent_entry *entry, 745 struct ftrace_graph_ent_entry *entry,
742 struct trace_seq *s, int cpu) 746 struct trace_seq *s, int cpu, u32 flags)
743{ 747{
744 struct ftrace_graph_ent *call = &entry->graph_ent; 748 struct ftrace_graph_ent *call = &entry->graph_ent;
745 struct fgraph_data *data = iter->private; 749 struct fgraph_data *data = iter->private;
@@ -759,12 +763,12 @@ print_graph_entry_nested(struct trace_iterator *iter,
759 } 763 }
760 764
761 /* No overhead */ 765 /* No overhead */
762 ret = print_graph_overhead(-1, s); 766 ret = print_graph_overhead(-1, s, flags);
763 if (!ret) 767 if (!ret)
764 return TRACE_TYPE_PARTIAL_LINE; 768 return TRACE_TYPE_PARTIAL_LINE;
765 769
766 /* No time */ 770 /* No time */
767 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) { 771 if (flags & TRACE_GRAPH_PRINT_DURATION) {
768 ret = trace_seq_printf(s, " | "); 772 ret = trace_seq_printf(s, " | ");
769 if (!ret) 773 if (!ret)
770 return TRACE_TYPE_PARTIAL_LINE; 774 return TRACE_TYPE_PARTIAL_LINE;
@@ -790,7 +794,7 @@ print_graph_entry_nested(struct trace_iterator *iter,
790 794
791static enum print_line_t 795static enum print_line_t
792print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s, 796print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
793 int type, unsigned long addr) 797 int type, unsigned long addr, u32 flags)
794{ 798{
795 struct fgraph_data *data = iter->private; 799 struct fgraph_data *data = iter->private;
796 struct trace_entry *ent = iter->ent; 800 struct trace_entry *ent = iter->ent;
@@ -803,27 +807,27 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
803 807
804 if (type) { 808 if (type) {
805 /* Interrupt */ 809 /* Interrupt */
806 ret = print_graph_irq(iter, addr, type, cpu, ent->pid); 810 ret = print_graph_irq(iter, addr, type, cpu, ent->pid, flags);
807 if (ret == TRACE_TYPE_PARTIAL_LINE) 811 if (ret == TRACE_TYPE_PARTIAL_LINE)
808 return TRACE_TYPE_PARTIAL_LINE; 812 return TRACE_TYPE_PARTIAL_LINE;
809 } 813 }
810 814
811 /* Absolute time */ 815 /* Absolute time */
812 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) { 816 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) {
813 ret = print_graph_abs_time(iter->ts, s); 817 ret = print_graph_abs_time(iter->ts, s);
814 if (!ret) 818 if (!ret)
815 return TRACE_TYPE_PARTIAL_LINE; 819 return TRACE_TYPE_PARTIAL_LINE;
816 } 820 }
817 821
818 /* Cpu */ 822 /* Cpu */
819 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) { 823 if (flags & TRACE_GRAPH_PRINT_CPU) {
820 ret = print_graph_cpu(s, cpu); 824 ret = print_graph_cpu(s, cpu);
821 if (ret == TRACE_TYPE_PARTIAL_LINE) 825 if (ret == TRACE_TYPE_PARTIAL_LINE)
822 return TRACE_TYPE_PARTIAL_LINE; 826 return TRACE_TYPE_PARTIAL_LINE;
823 } 827 }
824 828
825 /* Proc */ 829 /* Proc */
826 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) { 830 if (flags & TRACE_GRAPH_PRINT_PROC) {
827 ret = print_graph_proc(s, ent->pid); 831 ret = print_graph_proc(s, ent->pid);
828 if (ret == TRACE_TYPE_PARTIAL_LINE) 832 if (ret == TRACE_TYPE_PARTIAL_LINE)
829 return TRACE_TYPE_PARTIAL_LINE; 833 return TRACE_TYPE_PARTIAL_LINE;
@@ -845,7 +849,7 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
845 849
846static enum print_line_t 850static enum print_line_t
847print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s, 851print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
848 struct trace_iterator *iter) 852 struct trace_iterator *iter, u32 flags)
849{ 853{
850 struct fgraph_data *data = iter->private; 854 struct fgraph_data *data = iter->private;
851 struct ftrace_graph_ent *call = &field->graph_ent; 855 struct ftrace_graph_ent *call = &field->graph_ent;
@@ -853,14 +857,14 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
853 static enum print_line_t ret; 857 static enum print_line_t ret;
854 int cpu = iter->cpu; 858 int cpu = iter->cpu;
855 859
856 if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func)) 860 if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func, flags))
857 return TRACE_TYPE_PARTIAL_LINE; 861 return TRACE_TYPE_PARTIAL_LINE;
858 862
859 leaf_ret = get_return_for_leaf(iter, field); 863 leaf_ret = get_return_for_leaf(iter, field);
860 if (leaf_ret) 864 if (leaf_ret)
861 ret = print_graph_entry_leaf(iter, field, leaf_ret, s); 865 ret = print_graph_entry_leaf(iter, field, leaf_ret, s, flags);
862 else 866 else
863 ret = print_graph_entry_nested(iter, field, s, cpu); 867 ret = print_graph_entry_nested(iter, field, s, cpu, flags);
864 868
865 if (data) { 869 if (data) {
866 /* 870 /*
@@ -879,7 +883,8 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
879 883
880static enum print_line_t 884static enum print_line_t
881print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, 885print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
882 struct trace_entry *ent, struct trace_iterator *iter) 886 struct trace_entry *ent, struct trace_iterator *iter,
887 u32 flags)
883{ 888{
884 unsigned long long duration = trace->rettime - trace->calltime; 889 unsigned long long duration = trace->rettime - trace->calltime;
885 struct fgraph_data *data = iter->private; 890 struct fgraph_data *data = iter->private;
@@ -909,16 +914,16 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
909 } 914 }
910 } 915 }
911 916
912 if (print_graph_prologue(iter, s, 0, 0)) 917 if (print_graph_prologue(iter, s, 0, 0, flags))
913 return TRACE_TYPE_PARTIAL_LINE; 918 return TRACE_TYPE_PARTIAL_LINE;
914 919
915 /* Overhead */ 920 /* Overhead */
916 ret = print_graph_overhead(duration, s); 921 ret = print_graph_overhead(duration, s, flags);
917 if (!ret) 922 if (!ret)
918 return TRACE_TYPE_PARTIAL_LINE; 923 return TRACE_TYPE_PARTIAL_LINE;
919 924
920 /* Duration */ 925 /* Duration */
921 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) { 926 if (flags & TRACE_GRAPH_PRINT_DURATION) {
922 ret = print_graph_duration(duration, s); 927 ret = print_graph_duration(duration, s);
923 if (ret == TRACE_TYPE_PARTIAL_LINE) 928 if (ret == TRACE_TYPE_PARTIAL_LINE)
924 return TRACE_TYPE_PARTIAL_LINE; 929 return TRACE_TYPE_PARTIAL_LINE;
@@ -948,14 +953,15 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
948 } 953 }
949 954
950 /* Overrun */ 955 /* Overrun */
951 if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERRUN) { 956 if (flags & TRACE_GRAPH_PRINT_OVERRUN) {
952 ret = trace_seq_printf(s, " (Overruns: %lu)\n", 957 ret = trace_seq_printf(s, " (Overruns: %lu)\n",
953 trace->overrun); 958 trace->overrun);
954 if (!ret) 959 if (!ret)
955 return TRACE_TYPE_PARTIAL_LINE; 960 return TRACE_TYPE_PARTIAL_LINE;
956 } 961 }
957 962
958 ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET, cpu, pid); 963 ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET,
964 cpu, pid, flags);
959 if (ret == TRACE_TYPE_PARTIAL_LINE) 965 if (ret == TRACE_TYPE_PARTIAL_LINE)
960 return TRACE_TYPE_PARTIAL_LINE; 966 return TRACE_TYPE_PARTIAL_LINE;
961 967
@@ -963,8 +969,8 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
963} 969}
964 970
965static enum print_line_t 971static enum print_line_t
966print_graph_comment(struct trace_seq *s, struct trace_entry *ent, 972print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
967 struct trace_iterator *iter) 973 struct trace_iterator *iter, u32 flags)
968{ 974{
969 unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); 975 unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
970 struct fgraph_data *data = iter->private; 976 struct fgraph_data *data = iter->private;
@@ -976,16 +982,16 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
976 if (data) 982 if (data)
977 depth = per_cpu_ptr(data->cpu_data, iter->cpu)->depth; 983 depth = per_cpu_ptr(data->cpu_data, iter->cpu)->depth;
978 984
979 if (print_graph_prologue(iter, s, 0, 0)) 985 if (print_graph_prologue(iter, s, 0, 0, flags))
980 return TRACE_TYPE_PARTIAL_LINE; 986 return TRACE_TYPE_PARTIAL_LINE;
981 987
982 /* No overhead */ 988 /* No overhead */
983 ret = print_graph_overhead(-1, s); 989 ret = print_graph_overhead(-1, s, flags);
984 if (!ret) 990 if (!ret)
985 return TRACE_TYPE_PARTIAL_LINE; 991 return TRACE_TYPE_PARTIAL_LINE;
986 992
987 /* No time */ 993 /* No time */
988 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) { 994 if (flags & TRACE_GRAPH_PRINT_DURATION) {
989 ret = trace_seq_printf(s, " | "); 995 ret = trace_seq_printf(s, " | ");
990 if (!ret) 996 if (!ret)
991 return TRACE_TYPE_PARTIAL_LINE; 997 return TRACE_TYPE_PARTIAL_LINE;
@@ -1020,7 +1026,7 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
1020 if (!event) 1026 if (!event)
1021 return TRACE_TYPE_UNHANDLED; 1027 return TRACE_TYPE_UNHANDLED;
1022 1028
1023 ret = event->trace(iter, sym_flags); 1029 ret = event->funcs->trace(iter, sym_flags, event);
1024 if (ret != TRACE_TYPE_HANDLED) 1030 if (ret != TRACE_TYPE_HANDLED)
1025 return ret; 1031 return ret;
1026 } 1032 }
@@ -1040,7 +1046,7 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
1040 1046
1041 1047
1042enum print_line_t 1048enum print_line_t
1043print_graph_function(struct trace_iterator *iter) 1049print_graph_function_flags(struct trace_iterator *iter, u32 flags)
1044{ 1050{
1045 struct ftrace_graph_ent_entry *field; 1051 struct ftrace_graph_ent_entry *field;
1046 struct fgraph_data *data = iter->private; 1052 struct fgraph_data *data = iter->private;
@@ -1061,7 +1067,7 @@ print_graph_function(struct trace_iterator *iter)
1061 if (data && data->failed) { 1067 if (data && data->failed) {
1062 field = &data->ent; 1068 field = &data->ent;
1063 iter->cpu = data->cpu; 1069 iter->cpu = data->cpu;
1064 ret = print_graph_entry(field, s, iter); 1070 ret = print_graph_entry(field, s, iter, flags);
1065 if (ret == TRACE_TYPE_HANDLED && iter->cpu != cpu) { 1071 if (ret == TRACE_TYPE_HANDLED && iter->cpu != cpu) {
1066 per_cpu_ptr(data->cpu_data, iter->cpu)->ignore = 1; 1072 per_cpu_ptr(data->cpu_data, iter->cpu)->ignore = 1;
1067 ret = TRACE_TYPE_NO_CONSUME; 1073 ret = TRACE_TYPE_NO_CONSUME;
@@ -1081,32 +1087,50 @@ print_graph_function(struct trace_iterator *iter)
1081 struct ftrace_graph_ent_entry saved; 1087 struct ftrace_graph_ent_entry saved;
1082 trace_assign_type(field, entry); 1088 trace_assign_type(field, entry);
1083 saved = *field; 1089 saved = *field;
1084 return print_graph_entry(&saved, s, iter); 1090 return print_graph_entry(&saved, s, iter, flags);
1085 } 1091 }
1086 case TRACE_GRAPH_RET: { 1092 case TRACE_GRAPH_RET: {
1087 struct ftrace_graph_ret_entry *field; 1093 struct ftrace_graph_ret_entry *field;
1088 trace_assign_type(field, entry); 1094 trace_assign_type(field, entry);
1089 return print_graph_return(&field->ret, s, entry, iter); 1095 return print_graph_return(&field->ret, s, entry, iter, flags);
1090 } 1096 }
1097 case TRACE_STACK:
1098 case TRACE_FN:
1099 /* dont trace stack and functions as comments */
1100 return TRACE_TYPE_UNHANDLED;
1101
1091 default: 1102 default:
1092 return print_graph_comment(s, entry, iter); 1103 return print_graph_comment(s, entry, iter, flags);
1093 } 1104 }
1094 1105
1095 return TRACE_TYPE_HANDLED; 1106 return TRACE_TYPE_HANDLED;
1096} 1107}
1097 1108
1098static void print_lat_header(struct seq_file *s) 1109static enum print_line_t
1110print_graph_function(struct trace_iterator *iter)
1111{
1112 return print_graph_function_flags(iter, tracer_flags.val);
1113}
1114
1115static enum print_line_t
1116print_graph_function_event(struct trace_iterator *iter, int flags,
1117 struct trace_event *event)
1118{
1119 return print_graph_function(iter);
1120}
1121
1122static void print_lat_header(struct seq_file *s, u32 flags)
1099{ 1123{
1100 static const char spaces[] = " " /* 16 spaces */ 1124 static const char spaces[] = " " /* 16 spaces */
1101 " " /* 4 spaces */ 1125 " " /* 4 spaces */
1102 " "; /* 17 spaces */ 1126 " "; /* 17 spaces */
1103 int size = 0; 1127 int size = 0;
1104 1128
1105 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) 1129 if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
1106 size += 16; 1130 size += 16;
1107 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) 1131 if (flags & TRACE_GRAPH_PRINT_CPU)
1108 size += 4; 1132 size += 4;
1109 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1133 if (flags & TRACE_GRAPH_PRINT_PROC)
1110 size += 17; 1134 size += 17;
1111 1135
1112 seq_printf(s, "#%.*s _-----=> irqs-off \n", size, spaces); 1136 seq_printf(s, "#%.*s _-----=> irqs-off \n", size, spaces);
@@ -1117,43 +1141,48 @@ static void print_lat_header(struct seq_file *s)
1117 seq_printf(s, "#%.*s|||| / \n", size, spaces); 1141 seq_printf(s, "#%.*s|||| / \n", size, spaces);
1118} 1142}
1119 1143
1120static void print_graph_headers(struct seq_file *s) 1144void print_graph_headers_flags(struct seq_file *s, u32 flags)
1121{ 1145{
1122 int lat = trace_flags & TRACE_ITER_LATENCY_FMT; 1146 int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
1123 1147
1124 if (lat) 1148 if (lat)
1125 print_lat_header(s); 1149 print_lat_header(s, flags);
1126 1150
1127 /* 1st line */ 1151 /* 1st line */
1128 seq_printf(s, "#"); 1152 seq_printf(s, "#");
1129 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) 1153 if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
1130 seq_printf(s, " TIME "); 1154 seq_printf(s, " TIME ");
1131 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) 1155 if (flags & TRACE_GRAPH_PRINT_CPU)
1132 seq_printf(s, " CPU"); 1156 seq_printf(s, " CPU");
1133 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1157 if (flags & TRACE_GRAPH_PRINT_PROC)
1134 seq_printf(s, " TASK/PID "); 1158 seq_printf(s, " TASK/PID ");
1135 if (lat) 1159 if (lat)
1136 seq_printf(s, "|||||"); 1160 seq_printf(s, "|||||");
1137 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 1161 if (flags & TRACE_GRAPH_PRINT_DURATION)
1138 seq_printf(s, " DURATION "); 1162 seq_printf(s, " DURATION ");
1139 seq_printf(s, " FUNCTION CALLS\n"); 1163 seq_printf(s, " FUNCTION CALLS\n");
1140 1164
1141 /* 2nd line */ 1165 /* 2nd line */
1142 seq_printf(s, "#"); 1166 seq_printf(s, "#");
1143 if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) 1167 if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
1144 seq_printf(s, " | "); 1168 seq_printf(s, " | ");
1145 if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) 1169 if (flags & TRACE_GRAPH_PRINT_CPU)
1146 seq_printf(s, " | "); 1170 seq_printf(s, " | ");
1147 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1171 if (flags & TRACE_GRAPH_PRINT_PROC)
1148 seq_printf(s, " | | "); 1172 seq_printf(s, " | | ");
1149 if (lat) 1173 if (lat)
1150 seq_printf(s, "|||||"); 1174 seq_printf(s, "|||||");
1151 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 1175 if (flags & TRACE_GRAPH_PRINT_DURATION)
1152 seq_printf(s, " | | "); 1176 seq_printf(s, " | | ");
1153 seq_printf(s, " | | | |\n"); 1177 seq_printf(s, " | | | |\n");
1154} 1178}
1155 1179
1156static void graph_trace_open(struct trace_iterator *iter) 1180void print_graph_headers(struct seq_file *s)
1181{
1182 print_graph_headers_flags(s, tracer_flags.val);
1183}
1184
1185void graph_trace_open(struct trace_iterator *iter)
1157{ 1186{
1158 /* pid and depth on the last trace processed */ 1187 /* pid and depth on the last trace processed */
1159 struct fgraph_data *data; 1188 struct fgraph_data *data;
@@ -1188,7 +1217,7 @@ static void graph_trace_open(struct trace_iterator *iter)
1188 pr_warning("function graph tracer: not enough memory\n"); 1217 pr_warning("function graph tracer: not enough memory\n");
1189} 1218}
1190 1219
1191static void graph_trace_close(struct trace_iterator *iter) 1220void graph_trace_close(struct trace_iterator *iter)
1192{ 1221{
1193 struct fgraph_data *data = iter->private; 1222 struct fgraph_data *data = iter->private;
1194 1223
@@ -1198,6 +1227,20 @@ static void graph_trace_close(struct trace_iterator *iter)
1198 } 1227 }
1199} 1228}
1200 1229
1230static struct trace_event_functions graph_functions = {
1231 .trace = print_graph_function_event,
1232};
1233
1234static struct trace_event graph_trace_entry_event = {
1235 .type = TRACE_GRAPH_ENT,
1236 .funcs = &graph_functions,
1237};
1238
1239static struct trace_event graph_trace_ret_event = {
1240 .type = TRACE_GRAPH_RET,
1241 .funcs = &graph_functions
1242};
1243
1201static struct tracer graph_trace __read_mostly = { 1244static struct tracer graph_trace __read_mostly = {
1202 .name = "function_graph", 1245 .name = "function_graph",
1203 .open = graph_trace_open, 1246 .open = graph_trace_open,
@@ -1219,6 +1262,16 @@ static __init int init_graph_trace(void)
1219{ 1262{
1220 max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1); 1263 max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1);
1221 1264
1265 if (!register_ftrace_event(&graph_trace_entry_event)) {
1266 pr_warning("Warning: could not register graph trace events\n");
1267 return 1;
1268 }
1269
1270 if (!register_ftrace_event(&graph_trace_ret_event)) {
1271 pr_warning("Warning: could not register graph trace events\n");
1272 return 1;
1273 }
1274
1222 return register_tracer(&graph_trace); 1275 return register_tracer(&graph_trace);
1223} 1276}
1224 1277