aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-report.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r--tools/perf/builtin-report.c211
1 files changed, 34 insertions, 177 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 12f8c868fcd7..87c4582303bf 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -26,6 +26,7 @@
26#include "util/parse-options.h" 26#include "util/parse-options.h"
27#include "util/parse-events.h" 27#include "util/parse-events.h"
28 28
29#include "util/data_map.h"
29#include "util/thread.h" 30#include "util/thread.h"
30#include "util/sort.h" 31#include "util/sort.h"
31#include "util/hist.h" 32#include "util/hist.h"
@@ -37,7 +38,6 @@ static char *dso_list_str, *comm_list_str, *sym_list_str,
37static struct strlist *dso_list, *comm_list, *sym_list; 38static struct strlist *dso_list, *comm_list, *sym_list;
38 39
39static int force; 40static int force;
40static int input;
41 41
42static int full_paths; 42static int full_paths;
43static int show_nr_samples; 43static int show_nr_samples;
@@ -48,15 +48,11 @@ static struct perf_read_values show_threads_values;
48static char default_pretty_printing_style[] = "normal"; 48static char default_pretty_printing_style[] = "normal";
49static char *pretty_printing_style = default_pretty_printing_style; 49static char *pretty_printing_style = default_pretty_printing_style;
50 50
51static unsigned long page_size;
52static unsigned long mmap_window = 32;
53
54static int exclude_other = 1; 51static int exclude_other = 1;
55 52
56static char callchain_default_opt[] = "fractal,0.5"; 53static char callchain_default_opt[] = "fractal,0.5";
57 54
58static char __cwd[PATH_MAX]; 55static char *cwd;
59static char *cwd = __cwd;
60static int cwdlen; 56static int cwdlen;
61 57
62static struct rb_root threads; 58static struct rb_root threads;
@@ -815,208 +811,71 @@ process_read_event(event_t *event, unsigned long offset, unsigned long head)
815 return 0; 811 return 0;
816} 812}
817 813
818static int 814static int sample_type_check(u64 type)
819process_event(event_t *event, unsigned long offset, unsigned long head)
820{
821 trace_event(event);
822
823 switch (event->header.type) {
824 case PERF_RECORD_SAMPLE:
825 return process_sample_event(event, offset, head);
826
827 case PERF_RECORD_MMAP:
828 return process_mmap_event(event, offset, head);
829
830 case PERF_RECORD_COMM:
831 return process_comm_event(event, offset, head);
832
833 case PERF_RECORD_FORK:
834 case PERF_RECORD_EXIT:
835 return process_task_event(event, offset, head);
836
837 case PERF_RECORD_LOST:
838 return process_lost_event(event, offset, head);
839
840 case PERF_RECORD_READ:
841 return process_read_event(event, offset, head);
842
843 /*
844 * We dont process them right now but they are fine:
845 */
846
847 case PERF_RECORD_THROTTLE:
848 case PERF_RECORD_UNTHROTTLE:
849 return 0;
850
851 default:
852 return -1;
853 }
854
855 return 0;
856}
857
858static int __cmd_report(void)
859{ 815{
860 int ret, rc = EXIT_FAILURE; 816 sample_type = type;
861 unsigned long offset = 0;
862 unsigned long head, shift;
863 struct stat input_stat;
864 struct thread *idle;
865 event_t *event;
866 uint32_t size;
867 char *buf;
868
869 idle = register_idle_thread(&threads, &last_match);
870 thread__comm_adjust(idle);
871
872 if (show_threads)
873 perf_read_values_init(&show_threads_values);
874
875 input = open(input_name, O_RDONLY);
876 if (input < 0) {
877 fprintf(stderr, " failed to open file: %s", input_name);
878 if (!strcmp(input_name, "perf.data"))
879 fprintf(stderr, " (try 'perf record' first)");
880 fprintf(stderr, "\n");
881 exit(-1);
882 }
883
884 ret = fstat(input, &input_stat);
885 if (ret < 0) {
886 perror("failed to stat file");
887 exit(-1);
888 }
889
890 if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
891 fprintf(stderr, "file: %s not owned by current user or root\n", input_name);
892 exit(-1);
893 }
894
895 if (!input_stat.st_size) {
896 fprintf(stderr, "zero-sized file, nothing to do!\n");
897 exit(0);
898 }
899
900 header = perf_header__read(input);
901 head = header->data_offset;
902
903 sample_type = perf_header__sample_type(header);
904 817
905 if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) { 818 if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
906 if (sort__has_parent) { 819 if (sort__has_parent) {
907 fprintf(stderr, "selected --sort parent, but no" 820 fprintf(stderr, "selected --sort parent, but no"
908 " callchain data. Did you call" 821 " callchain data. Did you call"
909 " perf record without -g?\n"); 822 " perf record without -g?\n");
910 exit(-1); 823 return -1;
911 } 824 }
912 if (callchain) { 825 if (callchain) {
913 fprintf(stderr, "selected -g but no callchain data." 826 fprintf(stderr, "selected -g but no callchain data."
914 " Did you call perf record without" 827 " Did you call perf record without"
915 " -g?\n"); 828 " -g?\n");
916 exit(-1); 829 return -1;
917 } 830 }
918 } else if (callchain_param.mode != CHAIN_NONE && !callchain) { 831 } else if (callchain_param.mode != CHAIN_NONE && !callchain) {
919 callchain = 1; 832 callchain = 1;
920 if (register_callchain_param(&callchain_param) < 0) { 833 if (register_callchain_param(&callchain_param) < 0) {
921 fprintf(stderr, "Can't register callchain" 834 fprintf(stderr, "Can't register callchain"
922 " params\n"); 835 " params\n");
923 exit(-1); 836 return -1;
924 } 837 }
925 } 838 }
926 839
927 if (load_kernel() < 0) { 840 return 0;
928 perror("failed to load kernel symbols"); 841}
929 return EXIT_FAILURE;
930 }
931
932 if (!full_paths) {
933 if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
934 perror("failed to get the current directory");
935 return EXIT_FAILURE;
936 }
937 cwdlen = strlen(cwd);
938 } else {
939 cwd = NULL;
940 cwdlen = 0;
941 }
942
943 shift = page_size * (head / page_size);
944 offset += shift;
945 head -= shift;
946
947remap:
948 buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
949 MAP_SHARED, input, offset);
950 if (buf == MAP_FAILED) {
951 perror("failed to mmap file");
952 exit(-1);
953 }
954
955more:
956 event = (event_t *)(buf + head);
957
958 size = event->header.size;
959 if (!size)
960 size = 8;
961
962 if (head + event->header.size >= page_size * mmap_window) {
963 int munmap_ret;
964
965 shift = page_size * (head / page_size);
966
967 munmap_ret = munmap(buf, page_size * mmap_window);
968 assert(munmap_ret == 0);
969
970 offset += shift;
971 head -= shift;
972 goto remap;
973 }
974
975 size = event->header.size;
976
977 dump_printf("\n%p [%p]: event: %d\n",
978 (void *)(offset + head),
979 (void *)(long)event->header.size,
980 event->header.type);
981
982 if (!size || process_event(event, offset, head) < 0) {
983
984 dump_printf("%p [%p]: skipping unknown header type: %d\n",
985 (void *)(offset + head),
986 (void *)(long)(event->header.size),
987 event->header.type);
988
989 total_unknown++;
990 842
991 /* 843static struct perf_file_handler file_handler = {
992 * assume we lost track of the stream, check alignment, and 844 .process_sample_event = process_sample_event,
993 * increment a single u64 in the hope to catch on again 'soon'. 845 .process_mmap_event = process_mmap_event,
994 */ 846 .process_comm_event = process_comm_event,
847 .process_exit_event = process_task_event,
848 .process_fork_event = process_task_event,
849 .process_lost_event = process_lost_event,
850 .process_read_event = process_read_event,
851 .sample_type_check = sample_type_check,
852};
995 853
996 if (unlikely(head & 7))
997 head &= ~7ULL;
998 854
999 size = 8; 855static int __cmd_report(void)
1000 } 856{
857 struct thread *idle;
858 int ret;
1001 859
1002 head += size; 860 idle = register_idle_thread(&threads, &last_match);
861 thread__comm_adjust(idle);
1003 862
1004 if (offset + head >= header->data_offset + header->data_size) 863 if (show_threads)
1005 goto done; 864 perf_read_values_init(&show_threads_values);
1006 865
1007 if (offset + head < (unsigned long)input_stat.st_size) 866 register_perf_file_handler(&file_handler);
1008 goto more;
1009 867
1010done: 868 ret = mmap_dispatch_perf_file(&header, input_name, force, full_paths,
1011 rc = EXIT_SUCCESS; 869 &cwdlen, &cwd);
1012 close(input); 870 if (ret)
871 return ret;
1013 872
1014 dump_printf(" IP events: %10ld\n", total); 873 dump_printf(" IP events: %10ld\n", total);
1015 dump_printf(" mmap events: %10ld\n", total_mmap); 874 dump_printf(" mmap events: %10ld\n", total_mmap);
1016 dump_printf(" comm events: %10ld\n", total_comm); 875 dump_printf(" comm events: %10ld\n", total_comm);
1017 dump_printf(" fork events: %10ld\n", total_fork); 876 dump_printf(" fork events: %10ld\n", total_fork);
1018 dump_printf(" lost events: %10ld\n", total_lost); 877 dump_printf(" lost events: %10ld\n", total_lost);
1019 dump_printf(" unknown events: %10ld\n", total_unknown); 878 dump_printf(" unknown events: %10ld\n", file_handler.total_unknown);
1020 879
1021 if (dump_trace) 880 if (dump_trace)
1022 return 0; 881 return 0;
@@ -1034,7 +893,7 @@ done:
1034 if (show_threads) 893 if (show_threads)
1035 perf_read_values_destroy(&show_threads_values); 894 perf_read_values_destroy(&show_threads_values);
1036 895
1037 return rc; 896 return ret;
1038} 897}
1039 898
1040static int 899static int
@@ -1177,8 +1036,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
1177{ 1036{
1178 symbol__init(); 1037 symbol__init();
1179 1038
1180 page_size = getpagesize();
1181
1182 argc = parse_options(argc, argv, options, report_usage, 0); 1039 argc = parse_options(argc, argv, options, report_usage, 0);
1183 1040
1184 setup_sorting(); 1041 setup_sorting();