aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/perf_counter/builtin-report.c211
1 files changed, 118 insertions, 93 deletions
diff --git a/Documentation/perf_counter/builtin-report.c b/Documentation/perf_counter/builtin-report.c
index 333d31269e3f..82b62529e659 100644
--- a/Documentation/perf_counter/builtin-report.c
+++ b/Documentation/perf_counter/builtin-report.c
@@ -50,6 +50,7 @@ struct ip_event {
50 __u64 ip; 50 __u64 ip;
51 __u32 pid, tid; 51 __u32 pid, tid;
52}; 52};
53
53struct mmap_event { 54struct mmap_event {
54 struct perf_event_header header; 55 struct perf_event_header header;
55 __u32 pid, tid; 56 __u32 pid, tid;
@@ -58,9 +59,10 @@ struct mmap_event {
58 __u64 pgoff; 59 __u64 pgoff;
59 char filename[PATH_MAX]; 60 char filename[PATH_MAX];
60}; 61};
62
61struct comm_event { 63struct comm_event {
62 struct perf_event_header header; 64 struct perf_event_header header;
63 __u32 pid,tid; 65 __u32 pid, tid;
64 char comm[16]; 66 char comm[16];
65}; 67};
66 68
@@ -760,114 +762,137 @@ static void register_idle_thread(void)
760static unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0; 762static unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0;
761 763
762static int 764static int
763process_event(event_t *event, unsigned long offset, unsigned long head) 765process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
764{ 766{
765 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { 767 char level;
766 char level; 768 int show = 0;
767 int show = 0; 769 struct dso *dso = NULL;
768 struct dso *dso = NULL; 770 struct thread *thread = threads__findnew(event->ip.pid);
769 struct thread *thread = threads__findnew(event->ip.pid); 771 uint64_t ip = event->ip.ip;
770 uint64_t ip = event->ip.ip; 772 struct map *map = NULL;
771 struct map *map = NULL; 773
772 774 dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p\n",
773 dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p\n", 775 (void *)(offset + head),
774 (void *)(offset + head), 776 (void *)(long)(event->header.size),
775 (void *)(long)(event->header.size), 777 event->header.misc,
776 event->header.misc, 778 event->ip.pid,
777 event->ip.pid, 779 (void *)(long)ip);
778 (void *)(long)ip); 780
779 781 dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
780 dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid); 782
781 783 if (thread == NULL) {
782 if (thread == NULL) { 784 fprintf(stderr, "problem processing %d event, skipping it.\n",
783 fprintf(stderr, "problem processing %d event, skipping it.\n", 785 event->header.type);
784 event->header.type); 786 return -1;
785 return -1; 787 }
786 }
787
788 if (event->header.misc & PERF_EVENT_MISC_KERNEL) {
789 show = SHOW_KERNEL;
790 level = 'k';
791 788
792 dso = kernel_dso; 789 if (event->header.misc & PERF_EVENT_MISC_KERNEL) {
790 show = SHOW_KERNEL;
791 level = 'k';
793 792
794 dprintf(" ...... dso: %s\n", dso->name); 793 dso = kernel_dso;
795 794
796 } else if (event->header.misc & PERF_EVENT_MISC_USER) { 795 dprintf(" ...... dso: %s\n", dso->name);
797 796
798 show = SHOW_USER; 797 } else if (event->header.misc & PERF_EVENT_MISC_USER) {
799 level = '.';
800 798
801 map = thread__find_map(thread, ip); 799 show = SHOW_USER;
802 if (map != NULL) { 800 level = '.';
803 dso = map->dso;
804 ip -= map->start + map->pgoff;
805 } else {
806 /*
807 * If this is outside of all known maps,
808 * and is a negative address, try to look it
809 * up in the kernel dso, as it might be a
810 * vsyscall (which executes in user-mode):
811 */
812 if ((long long)ip < 0)
813 dso = kernel_dso;
814 }
815 dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
816 801
802 map = thread__find_map(thread, ip);
803 if (map != NULL) {
804 dso = map->dso;
805 ip -= map->start + map->pgoff;
817 } else { 806 } else {
818 show = SHOW_HV; 807 /*
819 level = 'H'; 808 * If this is outside of all known maps,
820 dprintf(" ...... dso: [hypervisor]\n"); 809 * and is a negative address, try to look it
810 * up in the kernel dso, as it might be a
811 * vsyscall (which executes in user-mode):
812 */
813 if ((long long)ip < 0)
814 dso = kernel_dso;
821 } 815 }
816 dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
822 817
823 if (show & show_mask) { 818 } else {
824 struct symbol *sym = dso__find_symbol(dso, ip); 819 show = SHOW_HV;
820 level = 'H';
821 dprintf(" ...... dso: [hypervisor]\n");
822 }
825 823
826 if (hist_entry__add(thread, map, dso, sym, ip, level)) { 824 if (show & show_mask) {
827 fprintf(stderr, 825 struct symbol *sym = dso__find_symbol(dso, ip);
828 "problem incrementing symbol count, skipping event\n");
829 return -1;
830 }
831 }
832 total++;
833 } else switch (event->header.type) {
834 case PERF_EVENT_MMAP: {
835 struct thread *thread = threads__findnew(event->mmap.pid);
836 struct map *map = map__new(&event->mmap);
837 826
838 dprintf("%p [%p]: PERF_EVENT_MMAP: [%p(%p) @ %p]: %s\n", 827 if (hist_entry__add(thread, map, dso, sym, ip, level)) {
839 (void *)(offset + head), 828 fprintf(stderr,
840 (void *)(long)(event->header.size), 829 "problem incrementing symbol count, skipping event\n");
841 (void *)(long)event->mmap.start,
842 (void *)(long)event->mmap.len,
843 (void *)(long)event->mmap.pgoff,
844 event->mmap.filename);
845
846 if (thread == NULL || map == NULL) {
847 if (verbose)
848 fprintf(stderr, "problem processing PERF_EVENT_MMAP, skipping event.\n");
849 return -1; 830 return -1;
850 } 831 }
851 thread__insert_map(thread, map);
852 total_mmap++;
853 break;
854 } 832 }
855 case PERF_EVENT_COMM: { 833 total++;
856 struct thread *thread = threads__findnew(event->comm.pid);
857 834
858 dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n", 835 return 0;
859 (void *)(offset + head), 836}
860 (void *)(long)(event->header.size),
861 event->comm.comm, event->comm.pid);
862 837
863 if (thread == NULL || 838static int
864 thread__set_comm(thread, event->comm.comm)) { 839process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
865 fprintf(stderr, "problem processing PERF_EVENT_COMM, skipping event.\n"); 840{
866 return -1; 841 struct thread *thread = threads__findnew(event->mmap.pid);
867 } 842 struct map *map = map__new(&event->mmap);
868 total_comm++; 843
869 break; 844 dprintf("%p [%p]: PERF_EVENT_MMAP: [%p(%p) @ %p]: %s\n",
845 (void *)(offset + head),
846 (void *)(long)(event->header.size),
847 (void *)(long)event->mmap.start,
848 (void *)(long)event->mmap.len,
849 (void *)(long)event->mmap.pgoff,
850 event->mmap.filename);
851
852 if (thread == NULL || map == NULL) {
853 dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n");
854 return -1;
855 }
856
857 thread__insert_map(thread, map);
858 total_mmap++;
859
860 return 0;
861}
862
863static int
864process_comm_event(event_t *event, unsigned long offset, unsigned long head)
865{
866 struct thread *thread = threads__findnew(event->comm.pid);
867
868 dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
869 (void *)(offset + head),
870 (void *)(long)(event->header.size),
871 event->comm.comm, event->comm.pid);
872
873 if (thread == NULL ||
874 thread__set_comm(thread, event->comm.comm)) {
875 dprintf("problem processing PERF_EVENT_COMM, skipping event.\n");
876 return -1;
870 } 877 }
878 total_comm++;
879
880 return 0;
881}
882
883static int
884process_event(event_t *event, unsigned long offset, unsigned long head)
885{
886 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW)
887 return process_overflow_event(event, offset, head);
888
889 switch (event->header.type) {
890 case PERF_EVENT_MMAP:
891 return process_mmap_event(event, offset, head);
892
893 case PERF_EVENT_COMM:
894 return process_comm_event(event, offset, head);
895
871 default: 896 default:
872 return -1; 897 return -1;
873 } 898 }
@@ -877,13 +902,13 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
877 902
878static int __cmd_report(void) 903static int __cmd_report(void)
879{ 904{
905 int ret, rc = EXIT_FAILURE;
880 unsigned long offset = 0; 906 unsigned long offset = 0;
881 unsigned long head = 0; 907 unsigned long head = 0;
882 struct stat stat; 908 struct stat stat;
883 char *buf;
884 event_t *event; 909 event_t *event;
885 int ret, rc = EXIT_FAILURE;
886 uint32_t size; 910 uint32_t size;
911 char *buf;
887 912
888 register_idle_thread(); 913 register_idle_thread();
889 914