aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/perf_counter/builtin-report.c186
1 files changed, 98 insertions, 88 deletions
diff --git a/Documentation/perf_counter/builtin-report.c b/Documentation/perf_counter/builtin-report.c
index 33b3b15fb014..333d31269e3f 100644
--- a/Documentation/perf_counter/builtin-report.c
+++ b/Documentation/perf_counter/builtin-report.c
@@ -147,7 +147,11 @@ static int load_kernel(void)
147 return err; 147 return err;
148} 148}
149 149
150static int strcommon(const char *pathname, const char *cwd, int cwdlen) 150static char __cwd[PATH_MAX];
151static char *cwd = __cwd;
152static int cwdlen;
153
154static int strcommon(const char *pathname)
151{ 155{
152 int n = 0; 156 int n = 0;
153 157
@@ -165,7 +169,7 @@ struct map {
165 struct dso *dso; 169 struct dso *dso;
166}; 170};
167 171
168static struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen) 172static struct map *map__new(struct mmap_event *event)
169{ 173{
170 struct map *self = malloc(sizeof(*self)); 174 struct map *self = malloc(sizeof(*self));
171 175
@@ -174,7 +178,8 @@ static struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen)
174 char newfilename[PATH_MAX]; 178 char newfilename[PATH_MAX];
175 179
176 if (cwd) { 180 if (cwd) {
177 int n = strcommon(filename, cwd, cwdlen); 181 int n = strcommon(filename);
182
178 if (n == cwdlen) { 183 if (n == cwdlen) {
179 snprintf(newfilename, sizeof(newfilename), 184 snprintf(newfilename, sizeof(newfilename),
180 ".%s", filename + n); 185 ".%s", filename + n);
@@ -752,85 +757,11 @@ static void register_idle_thread(void)
752 } 757 }
753} 758}
754 759
760static unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0;
755 761
756static int __cmd_report(void) 762static int
763process_event(event_t *event, unsigned long offset, unsigned long head)
757{ 764{
758 unsigned long offset = 0;
759 unsigned long head = 0;
760 struct stat stat;
761 char *buf;
762 event_t *event;
763 int ret, rc = EXIT_FAILURE;
764 uint32_t size;
765 unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0;
766 char cwd[PATH_MAX], *cwdp = cwd;
767 int cwdlen;
768
769 register_idle_thread();
770
771 input = open(input_name, O_RDONLY);
772 if (input < 0) {
773 perror("failed to open file");
774 exit(-1);
775 }
776
777 ret = fstat(input, &stat);
778 if (ret < 0) {
779 perror("failed to stat file");
780 exit(-1);
781 }
782
783 if (!stat.st_size) {
784 fprintf(stderr, "zero-sized file, nothing to do!\n");
785 exit(0);
786 }
787
788 if (load_kernel() < 0) {
789 perror("failed to load kernel symbols");
790 return EXIT_FAILURE;
791 }
792
793 if (!full_paths) {
794 if (getcwd(cwd, sizeof(cwd)) == NULL) {
795 perror("failed to get the current directory");
796 return EXIT_FAILURE;
797 }
798 cwdlen = strlen(cwd);
799 } else {
800 cwdp = NULL;
801 cwdlen = 0;
802 }
803remap:
804 buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
805 MAP_SHARED, input, offset);
806 if (buf == MAP_FAILED) {
807 perror("failed to mmap file");
808 exit(-1);
809 }
810
811more:
812 event = (event_t *)(buf + head);
813
814 size = event->header.size;
815 if (!size)
816 size = 8;
817
818 if (head + event->header.size >= page_size * mmap_window) {
819 unsigned long shift = page_size * (head / page_size);
820 int ret;
821
822 ret = munmap(buf, page_size * mmap_window);
823 assert(ret == 0);
824
825 offset += shift;
826 head -= shift;
827 goto remap;
828 }
829
830 size = event->header.size;
831 if (!size)
832 goto broken_event;
833
834 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { 765 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) {
835 char level; 766 char level;
836 int show = 0; 767 int show = 0;
@@ -851,7 +782,7 @@ more:
851 if (thread == NULL) { 782 if (thread == NULL) {
852 fprintf(stderr, "problem processing %d event, skipping it.\n", 783 fprintf(stderr, "problem processing %d event, skipping it.\n",
853 event->header.type); 784 event->header.type);
854 goto broken_event; 785 return -1;
855 } 786 }
856 787
857 if (event->header.misc & PERF_EVENT_MISC_KERNEL) { 788 if (event->header.misc & PERF_EVENT_MISC_KERNEL) {
@@ -895,14 +826,14 @@ more:
895 if (hist_entry__add(thread, map, dso, sym, ip, level)) { 826 if (hist_entry__add(thread, map, dso, sym, ip, level)) {
896 fprintf(stderr, 827 fprintf(stderr,
897 "problem incrementing symbol count, skipping event\n"); 828 "problem incrementing symbol count, skipping event\n");
898 goto broken_event; 829 return -1;
899 } 830 }
900 } 831 }
901 total++; 832 total++;
902 } else switch (event->header.type) { 833 } else switch (event->header.type) {
903 case PERF_EVENT_MMAP: { 834 case PERF_EVENT_MMAP: {
904 struct thread *thread = threads__findnew(event->mmap.pid); 835 struct thread *thread = threads__findnew(event->mmap.pid);
905 struct map *map = map__new(&event->mmap, cwdp, cwdlen); 836 struct map *map = map__new(&event->mmap);
906 837
907 dprintf("%p [%p]: PERF_EVENT_MMAP: [%p(%p) @ %p]: %s\n", 838 dprintf("%p [%p]: PERF_EVENT_MMAP: [%p(%p) @ %p]: %s\n",
908 (void *)(offset + head), 839 (void *)(offset + head),
@@ -915,7 +846,7 @@ more:
915 if (thread == NULL || map == NULL) { 846 if (thread == NULL || map == NULL) {
916 if (verbose) 847 if (verbose)
917 fprintf(stderr, "problem processing PERF_EVENT_MMAP, skipping event.\n"); 848 fprintf(stderr, "problem processing PERF_EVENT_MMAP, skipping event.\n");
918 goto broken_event; 849 return -1;
919 } 850 }
920 thread__insert_map(thread, map); 851 thread__insert_map(thread, map);
921 total_mmap++; 852 total_mmap++;
@@ -932,13 +863,93 @@ more:
932 if (thread == NULL || 863 if (thread == NULL ||
933 thread__set_comm(thread, event->comm.comm)) { 864 thread__set_comm(thread, event->comm.comm)) {
934 fprintf(stderr, "problem processing PERF_EVENT_COMM, skipping event.\n"); 865 fprintf(stderr, "problem processing PERF_EVENT_COMM, skipping event.\n");
935 goto broken_event; 866 return -1;
936 } 867 }
937 total_comm++; 868 total_comm++;
938 break; 869 break;
939 } 870 }
940 default: { 871 default:
941broken_event: 872 return -1;
873 }
874
875 return 0;
876}
877
878static int __cmd_report(void)
879{
880 unsigned long offset = 0;
881 unsigned long head = 0;
882 struct stat stat;
883 char *buf;
884 event_t *event;
885 int ret, rc = EXIT_FAILURE;
886 uint32_t size;
887
888 register_idle_thread();
889
890 input = open(input_name, O_RDONLY);
891 if (input < 0) {
892 perror("failed to open file");
893 exit(-1);
894 }
895
896 ret = fstat(input, &stat);
897 if (ret < 0) {
898 perror("failed to stat file");
899 exit(-1);
900 }
901
902 if (!stat.st_size) {
903 fprintf(stderr, "zero-sized file, nothing to do!\n");
904 exit(0);
905 }
906
907 if (load_kernel() < 0) {
908 perror("failed to load kernel symbols");
909 return EXIT_FAILURE;
910 }
911
912 if (!full_paths) {
913 if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
914 perror("failed to get the current directory");
915 return EXIT_FAILURE;
916 }
917 cwdlen = strlen(cwd);
918 } else {
919 cwd = NULL;
920 cwdlen = 0;
921 }
922remap:
923 buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
924 MAP_SHARED, input, offset);
925 if (buf == MAP_FAILED) {
926 perror("failed to mmap file");
927 exit(-1);
928 }
929
930more:
931 event = (event_t *)(buf + head);
932
933 size = event->header.size;
934 if (!size)
935 size = 8;
936
937 if (head + event->header.size >= page_size * mmap_window) {
938 unsigned long shift = page_size * (head / page_size);
939 int ret;
940
941 ret = munmap(buf, page_size * mmap_window);
942 assert(ret == 0);
943
944 offset += shift;
945 head -= shift;
946 goto remap;
947 }
948
949 size = event->header.size;
950
951 if (!size || process_event(event, offset, head) < 0) {
952
942 dprintf("%p [%p]: skipping unknown header type: %d\n", 953 dprintf("%p [%p]: skipping unknown header type: %d\n",
943 (void *)(offset + head), 954 (void *)(offset + head),
944 (void *)(long)(event->header.size), 955 (void *)(long)(event->header.size),
@@ -956,7 +967,6 @@ broken_event:
956 967
957 size = 8; 968 size = 8;
958 } 969 }
959 }
960 970
961 head += size; 971 head += size;
962 972