diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-04-15 03:13:26 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-04-15 03:13:26 -0400 |
commit | 84b13fd596522db47f9545d5124c30cc00dfdf5a (patch) | |
tree | c1f51b8fe43a59fb56ea43a18da88c0d0812dd7d /tools/perf/util | |
parent | f92128193094c288bc315db1694fafeaeb7ee1d0 (diff) | |
parent | a0cccc2e8e9fb16cbed3a117b30e3fbac3092ee3 (diff) |
Merge branch 'perf/live' into perf/core
Conflicts:
tools/perf/builtin-record.c
Merge reason: add the live tracing feature, resolve conflict.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/event.h | 35 | ||||
-rw-r--r-- | tools/perf/util/header.c | 361 | ||||
-rw-r--r-- | tools/perf/util/header.h | 38 | ||||
-rw-r--r-- | tools/perf/util/session.c | 192 | ||||
-rw-r--r-- | tools/perf/util/session.h | 10 | ||||
-rw-r--r-- | tools/perf/util/trace-event-info.c | 24 | ||||
-rw-r--r-- | tools/perf/util/trace-event-read.c | 89 | ||||
-rw-r--r-- | tools/perf/util/trace-event.h | 4 |
8 files changed, 672 insertions, 81 deletions
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 7f7cf8539cfe..e5740ea140ab 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -83,6 +83,37 @@ struct build_id_event { | |||
83 | char filename[]; | 83 | char filename[]; |
84 | }; | 84 | }; |
85 | 85 | ||
86 | enum perf_header_event_type { /* above any possible kernel type */ | ||
87 | PERF_RECORD_HEADER_ATTR = 64, | ||
88 | PERF_RECORD_HEADER_EVENT_TYPE = 65, | ||
89 | PERF_RECORD_HEADER_TRACING_DATA = 66, | ||
90 | PERF_RECORD_HEADER_BUILD_ID = 67, | ||
91 | PERF_RECORD_HEADER_MAX | ||
92 | }; | ||
93 | |||
94 | struct attr_event { | ||
95 | struct perf_event_header header; | ||
96 | struct perf_event_attr attr; | ||
97 | u64 id[]; | ||
98 | }; | ||
99 | |||
100 | #define MAX_EVENT_NAME 64 | ||
101 | |||
102 | struct perf_trace_event_type { | ||
103 | u64 event_id; | ||
104 | char name[MAX_EVENT_NAME]; | ||
105 | }; | ||
106 | |||
107 | struct event_type_event { | ||
108 | struct perf_event_header header; | ||
109 | struct perf_trace_event_type event_type; | ||
110 | }; | ||
111 | |||
112 | struct tracing_data_event { | ||
113 | struct perf_event_header header; | ||
114 | u32 size; | ||
115 | }; | ||
116 | |||
86 | typedef union event_union { | 117 | typedef union event_union { |
87 | struct perf_event_header header; | 118 | struct perf_event_header header; |
88 | struct ip_event ip; | 119 | struct ip_event ip; |
@@ -92,6 +123,10 @@ typedef union event_union { | |||
92 | struct lost_event lost; | 123 | struct lost_event lost; |
93 | struct read_event read; | 124 | struct read_event read; |
94 | struct sample_event sample; | 125 | struct sample_event sample; |
126 | struct attr_event attr; | ||
127 | struct event_type_event event_type; | ||
128 | struct tracing_data_event tracing_data; | ||
129 | struct build_id_event build_id; | ||
95 | } event_t; | 130 | } event_t; |
96 | 131 | ||
97 | struct events_stats { | 132 | struct events_stats { |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 6c9aa16ee51f..628173ba689e 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -99,13 +99,6 @@ int perf_header__add_attr(struct perf_header *self, | |||
99 | return 0; | 99 | return 0; |
100 | } | 100 | } |
101 | 101 | ||
102 | #define MAX_EVENT_NAME 64 | ||
103 | |||
104 | struct perf_trace_event_type { | ||
105 | u64 event_id; | ||
106 | char name[MAX_EVENT_NAME]; | ||
107 | }; | ||
108 | |||
109 | static int event_count; | 102 | static int event_count; |
110 | static struct perf_trace_event_type *events; | 103 | static struct perf_trace_event_type *events; |
111 | 104 | ||
@@ -427,6 +420,25 @@ out_free: | |||
427 | return err; | 420 | return err; |
428 | } | 421 | } |
429 | 422 | ||
423 | int perf_header__write_pipe(int fd) | ||
424 | { | ||
425 | struct perf_pipe_file_header f_header; | ||
426 | int err; | ||
427 | |||
428 | f_header = (struct perf_pipe_file_header){ | ||
429 | .magic = PERF_MAGIC, | ||
430 | .size = sizeof(f_header), | ||
431 | }; | ||
432 | |||
433 | err = do_write(fd, &f_header, sizeof(f_header)); | ||
434 | if (err < 0) { | ||
435 | pr_debug("failed to write perf pipe header\n"); | ||
436 | return err; | ||
437 | } | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
430 | int perf_header__write(struct perf_header *self, int fd, bool at_exit) | 442 | int perf_header__write(struct perf_header *self, int fd, bool at_exit) |
431 | { | 443 | { |
432 | struct perf_file_header f_header; | 444 | struct perf_file_header f_header; |
@@ -518,25 +530,10 @@ int perf_header__write(struct perf_header *self, int fd, bool at_exit) | |||
518 | return 0; | 530 | return 0; |
519 | } | 531 | } |
520 | 532 | ||
521 | static int do_read(int fd, void *buf, size_t size) | ||
522 | { | ||
523 | while (size) { | ||
524 | int ret = read(fd, buf, size); | ||
525 | |||
526 | if (ret <= 0) | ||
527 | return -1; | ||
528 | |||
529 | size -= ret; | ||
530 | buf += ret; | ||
531 | } | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static int perf_header__getbuffer64(struct perf_header *self, | 533 | static int perf_header__getbuffer64(struct perf_header *self, |
537 | int fd, void *buf, size_t size) | 534 | int fd, void *buf, size_t size) |
538 | { | 535 | { |
539 | if (do_read(fd, buf, size)) | 536 | if (do_read(fd, buf, size) <= 0) |
540 | return -1; | 537 | return -1; |
541 | 538 | ||
542 | if (self->needs_swap) | 539 | if (self->needs_swap) |
@@ -592,7 +589,7 @@ int perf_file_header__read(struct perf_file_header *self, | |||
592 | { | 589 | { |
593 | lseek(fd, 0, SEEK_SET); | 590 | lseek(fd, 0, SEEK_SET); |
594 | 591 | ||
595 | if (do_read(fd, self, sizeof(*self)) || | 592 | if (do_read(fd, self, sizeof(*self)) <= 0 || |
596 | memcmp(&self->magic, __perf_magic, sizeof(self->magic))) | 593 | memcmp(&self->magic, __perf_magic, sizeof(self->magic))) |
597 | return -1; | 594 | return -1; |
598 | 595 | ||
@@ -662,13 +659,51 @@ static int perf_file_section__process(struct perf_file_section *self, | |||
662 | return 0; | 659 | return 0; |
663 | } | 660 | } |
664 | 661 | ||
665 | int perf_header__read(struct perf_header *self, int fd) | 662 | static int perf_file_header__read_pipe(struct perf_pipe_file_header *self, |
663 | struct perf_header *ph, int fd) | ||
664 | { | ||
665 | if (do_read(fd, self, sizeof(*self)) <= 0 || | ||
666 | memcmp(&self->magic, __perf_magic, sizeof(self->magic))) | ||
667 | return -1; | ||
668 | |||
669 | if (self->size != sizeof(*self)) { | ||
670 | u64 size = bswap_64(self->size); | ||
671 | |||
672 | if (size != sizeof(*self)) | ||
673 | return -1; | ||
674 | |||
675 | ph->needs_swap = true; | ||
676 | } | ||
677 | |||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | static int perf_header__read_pipe(struct perf_session *session, int fd) | ||
682 | { | ||
683 | struct perf_header *self = &session->header; | ||
684 | struct perf_pipe_file_header f_header; | ||
685 | |||
686 | if (perf_file_header__read_pipe(&f_header, self, fd) < 0) { | ||
687 | pr_debug("incompatible file format\n"); | ||
688 | return -EINVAL; | ||
689 | } | ||
690 | |||
691 | session->fd = fd; | ||
692 | |||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | int perf_header__read(struct perf_session *session, int fd) | ||
666 | { | 697 | { |
698 | struct perf_header *self = &session->header; | ||
667 | struct perf_file_header f_header; | 699 | struct perf_file_header f_header; |
668 | struct perf_file_attr f_attr; | 700 | struct perf_file_attr f_attr; |
669 | u64 f_id; | 701 | u64 f_id; |
670 | int nr_attrs, nr_ids, i, j; | 702 | int nr_attrs, nr_ids, i, j; |
671 | 703 | ||
704 | if (session->fd_pipe) | ||
705 | return perf_header__read_pipe(session, fd); | ||
706 | |||
672 | if (perf_file_header__read(&f_header, self, fd) < 0) { | 707 | if (perf_file_header__read(&f_header, self, fd) < 0) { |
673 | pr_debug("incompatible file format\n"); | 708 | pr_debug("incompatible file format\n"); |
674 | return -EINVAL; | 709 | return -EINVAL; |
@@ -765,3 +800,279 @@ perf_header__find_attr(u64 id, struct perf_header *header) | |||
765 | 800 | ||
766 | return NULL; | 801 | return NULL; |
767 | } | 802 | } |
803 | |||
804 | int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id, | ||
805 | event__handler_t process, | ||
806 | struct perf_session *session) | ||
807 | { | ||
808 | event_t *ev; | ||
809 | size_t size; | ||
810 | int err; | ||
811 | |||
812 | size = sizeof(struct perf_event_attr); | ||
813 | size = ALIGN(size, sizeof(u64)); | ||
814 | size += sizeof(struct perf_event_header); | ||
815 | size += ids * sizeof(u64); | ||
816 | |||
817 | ev = malloc(size); | ||
818 | |||
819 | ev->attr.attr = *attr; | ||
820 | memcpy(ev->attr.id, id, ids * sizeof(u64)); | ||
821 | |||
822 | ev->attr.header.type = PERF_RECORD_HEADER_ATTR; | ||
823 | ev->attr.header.size = size; | ||
824 | |||
825 | err = process(ev, session); | ||
826 | |||
827 | free(ev); | ||
828 | |||
829 | return err; | ||
830 | } | ||
831 | |||
832 | int event__synthesize_attrs(struct perf_header *self, | ||
833 | event__handler_t process, | ||
834 | struct perf_session *session) | ||
835 | { | ||
836 | struct perf_header_attr *attr; | ||
837 | int i, err = 0; | ||
838 | |||
839 | for (i = 0; i < self->attrs; i++) { | ||
840 | attr = self->attr[i]; | ||
841 | |||
842 | err = event__synthesize_attr(&attr->attr, attr->ids, attr->id, | ||
843 | process, session); | ||
844 | if (err) { | ||
845 | pr_debug("failed to create perf header attribute\n"); | ||
846 | return err; | ||
847 | } | ||
848 | } | ||
849 | |||
850 | return err; | ||
851 | } | ||
852 | |||
853 | int event__process_attr(event_t *self, struct perf_session *session) | ||
854 | { | ||
855 | struct perf_header_attr *attr; | ||
856 | unsigned int i, ids, n_ids; | ||
857 | |||
858 | attr = perf_header_attr__new(&self->attr.attr); | ||
859 | if (attr == NULL) | ||
860 | return -ENOMEM; | ||
861 | |||
862 | ids = self->header.size; | ||
863 | ids -= (void *)&self->attr.id - (void *)self; | ||
864 | n_ids = ids / sizeof(u64); | ||
865 | |||
866 | for (i = 0; i < n_ids; i++) { | ||
867 | if (perf_header_attr__add_id(attr, self->attr.id[i]) < 0) { | ||
868 | perf_header_attr__delete(attr); | ||
869 | return -ENOMEM; | ||
870 | } | ||
871 | } | ||
872 | |||
873 | if (perf_header__add_attr(&session->header, attr) < 0) { | ||
874 | perf_header_attr__delete(attr); | ||
875 | return -ENOMEM; | ||
876 | } | ||
877 | |||
878 | perf_session__update_sample_type(session); | ||
879 | |||
880 | return 0; | ||
881 | } | ||
882 | |||
883 | int event__synthesize_event_type(u64 event_id, char *name, | ||
884 | event__handler_t process, | ||
885 | struct perf_session *session) | ||
886 | { | ||
887 | event_t ev; | ||
888 | size_t size = 0; | ||
889 | int err = 0; | ||
890 | |||
891 | memset(&ev, 0, sizeof(ev)); | ||
892 | |||
893 | ev.event_type.event_type.event_id = event_id; | ||
894 | memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME); | ||
895 | strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1); | ||
896 | |||
897 | ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE; | ||
898 | size = strlen(name); | ||
899 | size = ALIGN(size, sizeof(u64)); | ||
900 | ev.event_type.header.size = sizeof(ev.event_type) - | ||
901 | (sizeof(ev.event_type.event_type.name) - size); | ||
902 | |||
903 | err = process(&ev, session); | ||
904 | |||
905 | return err; | ||
906 | } | ||
907 | |||
908 | int event__synthesize_event_types(event__handler_t process, | ||
909 | struct perf_session *session) | ||
910 | { | ||
911 | struct perf_trace_event_type *type; | ||
912 | int i, err = 0; | ||
913 | |||
914 | for (i = 0; i < event_count; i++) { | ||
915 | type = &events[i]; | ||
916 | |||
917 | err = event__synthesize_event_type(type->event_id, type->name, | ||
918 | process, session); | ||
919 | if (err) { | ||
920 | pr_debug("failed to create perf header event type\n"); | ||
921 | return err; | ||
922 | } | ||
923 | } | ||
924 | |||
925 | return err; | ||
926 | } | ||
927 | |||
928 | int event__process_event_type(event_t *self, | ||
929 | struct perf_session *session __unused) | ||
930 | { | ||
931 | if (perf_header__push_event(self->event_type.event_type.event_id, | ||
932 | self->event_type.event_type.name) < 0) | ||
933 | return -ENOMEM; | ||
934 | |||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs, | ||
939 | int nb_events, | ||
940 | event__handler_t process, | ||
941 | struct perf_session *session __unused) | ||
942 | { | ||
943 | event_t ev; | ||
944 | ssize_t size = 0, aligned_size = 0, padding; | ||
945 | int err = 0; | ||
946 | |||
947 | memset(&ev, 0, sizeof(ev)); | ||
948 | |||
949 | ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; | ||
950 | size = read_tracing_data_size(fd, pattrs, nb_events); | ||
951 | if (size <= 0) | ||
952 | return size; | ||
953 | aligned_size = ALIGN(size, sizeof(u64)); | ||
954 | padding = aligned_size - size; | ||
955 | ev.tracing_data.header.size = sizeof(ev.tracing_data); | ||
956 | ev.tracing_data.size = aligned_size; | ||
957 | |||
958 | process(&ev, session); | ||
959 | |||
960 | err = read_tracing_data(fd, pattrs, nb_events); | ||
961 | write_padded(fd, NULL, 0, padding); | ||
962 | |||
963 | return aligned_size; | ||
964 | } | ||
965 | |||
966 | int event__process_tracing_data(event_t *self, | ||
967 | struct perf_session *session) | ||
968 | { | ||
969 | ssize_t size_read, padding, size = self->tracing_data.size; | ||
970 | off_t offset = lseek(session->fd, 0, SEEK_CUR); | ||
971 | char buf[BUFSIZ]; | ||
972 | |||
973 | /* setup for reading amidst mmap */ | ||
974 | lseek(session->fd, offset + sizeof(struct tracing_data_event), | ||
975 | SEEK_SET); | ||
976 | |||
977 | size_read = trace_report(session->fd); | ||
978 | |||
979 | padding = ALIGN(size_read, sizeof(u64)) - size_read; | ||
980 | |||
981 | if (read(session->fd, buf, padding) < 0) | ||
982 | die("reading input file"); | ||
983 | |||
984 | if (size_read + padding != size) | ||
985 | die("tracing data size mismatch"); | ||
986 | |||
987 | return size_read + padding; | ||
988 | } | ||
989 | |||
990 | int event__synthesize_build_id(struct dso *pos, u16 misc, | ||
991 | event__handler_t process, | ||
992 | struct perf_session *session) | ||
993 | { | ||
994 | event_t ev; | ||
995 | size_t len; | ||
996 | int err = 0; | ||
997 | |||
998 | if (!pos->hit) | ||
999 | return err; | ||
1000 | |||
1001 | memset(&ev, 0, sizeof(ev)); | ||
1002 | |||
1003 | len = pos->long_name_len + 1; | ||
1004 | len = ALIGN(len, NAME_ALIGN); | ||
1005 | memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id)); | ||
1006 | ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; | ||
1007 | ev.build_id.header.misc = misc; | ||
1008 | ev.build_id.header.size = sizeof(ev.build_id) + len; | ||
1009 | memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); | ||
1010 | |||
1011 | err = process(&ev, session); | ||
1012 | |||
1013 | return err; | ||
1014 | } | ||
1015 | |||
1016 | static int __event_synthesize_build_ids(struct list_head *head, u16 misc, | ||
1017 | event__handler_t process, | ||
1018 | struct perf_session *session) | ||
1019 | { | ||
1020 | struct dso *pos; | ||
1021 | |||
1022 | dsos__for_each_with_build_id(pos, head) { | ||
1023 | int err; | ||
1024 | if (!pos->hit) | ||
1025 | continue; | ||
1026 | |||
1027 | err = event__synthesize_build_id(pos, misc, process, session); | ||
1028 | if (err < 0) | ||
1029 | return err; | ||
1030 | } | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | int event__synthesize_build_ids(event__handler_t process, | ||
1036 | struct perf_session *session) | ||
1037 | { | ||
1038 | int err; | ||
1039 | |||
1040 | if (!dsos__read_build_ids(true)) | ||
1041 | return 0; | ||
1042 | |||
1043 | err = __event_synthesize_build_ids(&dsos__kernel, | ||
1044 | PERF_RECORD_MISC_KERNEL, | ||
1045 | process, session); | ||
1046 | if (err == 0) | ||
1047 | err = __event_synthesize_build_ids(&dsos__user, | ||
1048 | PERF_RECORD_MISC_USER, | ||
1049 | process, session); | ||
1050 | |||
1051 | if (err < 0) { | ||
1052 | pr_debug("failed to synthesize build ids\n"); | ||
1053 | return err; | ||
1054 | } | ||
1055 | |||
1056 | dsos__cache_build_ids(); | ||
1057 | |||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1061 | int event__process_build_id(event_t *self, | ||
1062 | struct perf_session *session __unused) | ||
1063 | { | ||
1064 | struct list_head *head = &dsos__user; | ||
1065 | struct dso *dso; | ||
1066 | |||
1067 | if (self->build_id.header.misc & PERF_RECORD_MISC_KERNEL) | ||
1068 | head = &dsos__kernel; | ||
1069 | |||
1070 | dso = __dsos__findnew(head, self->build_id.filename); | ||
1071 | if (dso != NULL) { | ||
1072 | dso__set_build_id(dso, &self->build_id.build_id); | ||
1073 | if (head == &dsos__kernel && self->build_id.filename[0] == '[') | ||
1074 | dso->kernel = 1; | ||
1075 | } | ||
1076 | |||
1077 | return 0; | ||
1078 | } | ||
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index c059f08cf877..4214e2375650 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h | |||
@@ -39,6 +39,11 @@ struct perf_file_header { | |||
39 | DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS); | 39 | DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS); |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct perf_pipe_file_header { | ||
43 | u64 magic; | ||
44 | u64 size; | ||
45 | }; | ||
46 | |||
42 | struct perf_header; | 47 | struct perf_header; |
43 | 48 | ||
44 | int perf_file_header__read(struct perf_file_header *self, | 49 | int perf_file_header__read(struct perf_file_header *self, |
@@ -60,8 +65,9 @@ struct perf_header { | |||
60 | int perf_header__init(struct perf_header *self); | 65 | int perf_header__init(struct perf_header *self); |
61 | void perf_header__exit(struct perf_header *self); | 66 | void perf_header__exit(struct perf_header *self); |
62 | 67 | ||
63 | int perf_header__read(struct perf_header *self, int fd); | 68 | int perf_header__read(struct perf_session *session, int fd); |
64 | int perf_header__write(struct perf_header *self, int fd, bool at_exit); | 69 | int perf_header__write(struct perf_header *self, int fd, bool at_exit); |
70 | int perf_header__write_pipe(int fd); | ||
65 | 71 | ||
66 | int perf_header__add_attr(struct perf_header *self, | 72 | int perf_header__add_attr(struct perf_header *self, |
67 | struct perf_header_attr *attr); | 73 | struct perf_header_attr *attr); |
@@ -89,4 +95,34 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, | |||
89 | const char *name, bool is_kallsyms); | 95 | const char *name, bool is_kallsyms); |
90 | int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir); | 96 | int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir); |
91 | 97 | ||
98 | int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id, | ||
99 | event__handler_t process, | ||
100 | struct perf_session *session); | ||
101 | int event__synthesize_attrs(struct perf_header *self, | ||
102 | event__handler_t process, | ||
103 | struct perf_session *session); | ||
104 | int event__process_attr(event_t *self, struct perf_session *session); | ||
105 | |||
106 | int event__synthesize_event_type(u64 event_id, char *name, | ||
107 | event__handler_t process, | ||
108 | struct perf_session *session); | ||
109 | int event__synthesize_event_types(event__handler_t process, | ||
110 | struct perf_session *session); | ||
111 | int event__process_event_type(event_t *self, | ||
112 | struct perf_session *session); | ||
113 | |||
114 | int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs, | ||
115 | int nb_events, | ||
116 | event__handler_t process, | ||
117 | struct perf_session *session); | ||
118 | int event__process_tracing_data(event_t *self, | ||
119 | struct perf_session *session); | ||
120 | |||
121 | int event__synthesize_build_id(struct dso *pos, u16 misc, | ||
122 | event__handler_t process, | ||
123 | struct perf_session *session); | ||
124 | int event__synthesize_build_ids(event__handler_t process, | ||
125 | struct perf_session *session); | ||
126 | int event__process_build_id(event_t *self, struct perf_session *session); | ||
127 | |||
92 | #endif /* __PERF_HEADER_H */ | 128 | #endif /* __PERF_HEADER_H */ |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index ddf288fca3eb..0fdf3ebef1e9 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -14,6 +14,16 @@ static int perf_session__open(struct perf_session *self, bool force) | |||
14 | { | 14 | { |
15 | struct stat input_stat; | 15 | struct stat input_stat; |
16 | 16 | ||
17 | if (!strcmp(self->filename, "-")) { | ||
18 | self->fd_pipe = true; | ||
19 | self->fd = STDIN_FILENO; | ||
20 | |||
21 | if (perf_header__read(self, self->fd) < 0) | ||
22 | pr_err("incompatible file format"); | ||
23 | |||
24 | return 0; | ||
25 | } | ||
26 | |||
17 | self->fd = open(self->filename, O_RDONLY); | 27 | self->fd = open(self->filename, O_RDONLY); |
18 | if (self->fd < 0) { | 28 | if (self->fd < 0) { |
19 | pr_err("failed to open file: %s", self->filename); | 29 | pr_err("failed to open file: %s", self->filename); |
@@ -38,7 +48,7 @@ static int perf_session__open(struct perf_session *self, bool force) | |||
38 | goto out_close; | 48 | goto out_close; |
39 | } | 49 | } |
40 | 50 | ||
41 | if (perf_header__read(&self->header, self->fd) < 0) { | 51 | if (perf_header__read(self, self->fd) < 0) { |
42 | pr_err("incompatible file format"); | 52 | pr_err("incompatible file format"); |
43 | goto out_close; | 53 | goto out_close; |
44 | } | 54 | } |
@@ -52,6 +62,11 @@ out_close: | |||
52 | return -1; | 62 | return -1; |
53 | } | 63 | } |
54 | 64 | ||
65 | void perf_session__update_sample_type(struct perf_session *self) | ||
66 | { | ||
67 | self->sample_type = perf_header__sample_type(&self->header); | ||
68 | } | ||
69 | |||
55 | struct perf_session *perf_session__new(const char *filename, int mode, bool force) | 70 | struct perf_session *perf_session__new(const char *filename, int mode, bool force) |
56 | { | 71 | { |
57 | size_t len = filename ? strlen(filename) + 1 : 0; | 72 | size_t len = filename ? strlen(filename) + 1 : 0; |
@@ -85,7 +100,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc | |||
85 | goto out_delete; | 100 | goto out_delete; |
86 | } | 101 | } |
87 | 102 | ||
88 | self->sample_type = perf_header__sample_type(&self->header); | 103 | perf_session__update_sample_type(self); |
89 | out: | 104 | out: |
90 | return self; | 105 | return self; |
91 | out_free: | 106 | out_free: |
@@ -185,6 +200,14 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) | |||
185 | handler->throttle = process_event_stub; | 200 | handler->throttle = process_event_stub; |
186 | if (handler->unthrottle == NULL) | 201 | if (handler->unthrottle == NULL) |
187 | handler->unthrottle = process_event_stub; | 202 | handler->unthrottle = process_event_stub; |
203 | if (handler->attr == NULL) | ||
204 | handler->attr = process_event_stub; | ||
205 | if (handler->event_type == NULL) | ||
206 | handler->event_type = process_event_stub; | ||
207 | if (handler->tracing_data == NULL) | ||
208 | handler->tracing_data = process_event_stub; | ||
209 | if (handler->build_id == NULL) | ||
210 | handler->build_id = process_event_stub; | ||
188 | } | 211 | } |
189 | 212 | ||
190 | static const char *event__name[] = { | 213 | static const char *event__name[] = { |
@@ -198,16 +221,23 @@ static const char *event__name[] = { | |||
198 | [PERF_RECORD_FORK] = "FORK", | 221 | [PERF_RECORD_FORK] = "FORK", |
199 | [PERF_RECORD_READ] = "READ", | 222 | [PERF_RECORD_READ] = "READ", |
200 | [PERF_RECORD_SAMPLE] = "SAMPLE", | 223 | [PERF_RECORD_SAMPLE] = "SAMPLE", |
224 | [PERF_RECORD_HEADER_ATTR] = "ATTR", | ||
225 | [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", | ||
226 | [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", | ||
227 | [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", | ||
201 | }; | 228 | }; |
202 | 229 | ||
203 | unsigned long event__total[PERF_RECORD_MAX]; | 230 | unsigned long event__total[PERF_RECORD_HEADER_MAX]; |
204 | 231 | ||
205 | void event__print_totals(void) | 232 | void event__print_totals(void) |
206 | { | 233 | { |
207 | int i; | 234 | int i; |
208 | for (i = 0; i < PERF_RECORD_MAX; ++i) | 235 | for (i = 0; i < PERF_RECORD_HEADER_MAX; ++i) { |
236 | if (!event__name[i]) | ||
237 | continue; | ||
209 | pr_info("%10s events: %10ld\n", | 238 | pr_info("%10s events: %10ld\n", |
210 | event__name[i], event__total[i]); | 239 | event__name[i], event__total[i]); |
240 | } | ||
211 | } | 241 | } |
212 | 242 | ||
213 | void mem_bswap_64(void *src, int byte_size) | 243 | void mem_bswap_64(void *src, int byte_size) |
@@ -261,6 +291,37 @@ static void event__read_swap(event_t *self) | |||
261 | self->read.id = bswap_64(self->read.id); | 291 | self->read.id = bswap_64(self->read.id); |
262 | } | 292 | } |
263 | 293 | ||
294 | static void event__attr_swap(event_t *self) | ||
295 | { | ||
296 | size_t size; | ||
297 | |||
298 | self->attr.attr.type = bswap_32(self->attr.attr.type); | ||
299 | self->attr.attr.size = bswap_32(self->attr.attr.size); | ||
300 | self->attr.attr.config = bswap_64(self->attr.attr.config); | ||
301 | self->attr.attr.sample_period = bswap_64(self->attr.attr.sample_period); | ||
302 | self->attr.attr.sample_type = bswap_64(self->attr.attr.sample_type); | ||
303 | self->attr.attr.read_format = bswap_64(self->attr.attr.read_format); | ||
304 | self->attr.attr.wakeup_events = bswap_32(self->attr.attr.wakeup_events); | ||
305 | self->attr.attr.bp_type = bswap_32(self->attr.attr.bp_type); | ||
306 | self->attr.attr.bp_addr = bswap_64(self->attr.attr.bp_addr); | ||
307 | self->attr.attr.bp_len = bswap_64(self->attr.attr.bp_len); | ||
308 | |||
309 | size = self->header.size; | ||
310 | size -= (void *)&self->attr.id - (void *)self; | ||
311 | mem_bswap_64(self->attr.id, size); | ||
312 | } | ||
313 | |||
314 | static void event__event_type_swap(event_t *self) | ||
315 | { | ||
316 | self->event_type.event_type.event_id = | ||
317 | bswap_64(self->event_type.event_type.event_id); | ||
318 | } | ||
319 | |||
320 | static void event__tracing_data_swap(event_t *self) | ||
321 | { | ||
322 | self->tracing_data.size = bswap_32(self->tracing_data.size); | ||
323 | } | ||
324 | |||
264 | typedef void (*event__swap_op)(event_t *self); | 325 | typedef void (*event__swap_op)(event_t *self); |
265 | 326 | ||
266 | static event__swap_op event__swap_ops[] = { | 327 | static event__swap_op event__swap_ops[] = { |
@@ -271,7 +332,11 @@ static event__swap_op event__swap_ops[] = { | |||
271 | [PERF_RECORD_LOST] = event__all64_swap, | 332 | [PERF_RECORD_LOST] = event__all64_swap, |
272 | [PERF_RECORD_READ] = event__read_swap, | 333 | [PERF_RECORD_READ] = event__read_swap, |
273 | [PERF_RECORD_SAMPLE] = event__all64_swap, | 334 | [PERF_RECORD_SAMPLE] = event__all64_swap, |
274 | [PERF_RECORD_MAX] = NULL, | 335 | [PERF_RECORD_HEADER_ATTR] = event__attr_swap, |
336 | [PERF_RECORD_HEADER_EVENT_TYPE] = event__event_type_swap, | ||
337 | [PERF_RECORD_HEADER_TRACING_DATA] = event__tracing_data_swap, | ||
338 | [PERF_RECORD_HEADER_BUILD_ID] = NULL, | ||
339 | [PERF_RECORD_HEADER_MAX] = NULL, | ||
275 | }; | 340 | }; |
276 | 341 | ||
277 | static int perf_session__process_event(struct perf_session *self, | 342 | static int perf_session__process_event(struct perf_session *self, |
@@ -281,7 +346,7 @@ static int perf_session__process_event(struct perf_session *self, | |||
281 | { | 346 | { |
282 | trace_event(event); | 347 | trace_event(event); |
283 | 348 | ||
284 | if (event->header.type < PERF_RECORD_MAX) { | 349 | if (event->header.type < PERF_RECORD_HEADER_MAX) { |
285 | dump_printf("%#Lx [%#x]: PERF_RECORD_%s", | 350 | dump_printf("%#Lx [%#x]: PERF_RECORD_%s", |
286 | offset + head, event->header.size, | 351 | offset + head, event->header.size, |
287 | event__name[event->header.type]); | 352 | event__name[event->header.type]); |
@@ -311,6 +376,16 @@ static int perf_session__process_event(struct perf_session *self, | |||
311 | return ops->throttle(event, self); | 376 | return ops->throttle(event, self); |
312 | case PERF_RECORD_UNTHROTTLE: | 377 | case PERF_RECORD_UNTHROTTLE: |
313 | return ops->unthrottle(event, self); | 378 | return ops->unthrottle(event, self); |
379 | case PERF_RECORD_HEADER_ATTR: | ||
380 | return ops->attr(event, self); | ||
381 | case PERF_RECORD_HEADER_EVENT_TYPE: | ||
382 | return ops->event_type(event, self); | ||
383 | case PERF_RECORD_HEADER_TRACING_DATA: | ||
384 | /* setup for reading amidst mmap */ | ||
385 | lseek(self->fd, offset + head, SEEK_SET); | ||
386 | return ops->tracing_data(event, self); | ||
387 | case PERF_RECORD_HEADER_BUILD_ID: | ||
388 | return ops->build_id(event, self); | ||
314 | default: | 389 | default: |
315 | self->unknown_events++; | 390 | self->unknown_events++; |
316 | return -1; | 391 | return -1; |
@@ -376,6 +451,101 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se | |||
376 | return thread; | 451 | return thread; |
377 | } | 452 | } |
378 | 453 | ||
454 | int do_read(int fd, void *buf, size_t size) | ||
455 | { | ||
456 | void *buf_start = buf; | ||
457 | |||
458 | while (size) { | ||
459 | int ret = read(fd, buf, size); | ||
460 | |||
461 | if (ret <= 0) | ||
462 | return ret; | ||
463 | |||
464 | size -= ret; | ||
465 | buf += ret; | ||
466 | } | ||
467 | |||
468 | return buf - buf_start; | ||
469 | } | ||
470 | |||
471 | #define session_done() (*(volatile int *)(&session_done)) | ||
472 | volatile int session_done; | ||
473 | |||
474 | static int __perf_session__process_pipe_events(struct perf_session *self, | ||
475 | struct perf_event_ops *ops) | ||
476 | { | ||
477 | event_t event; | ||
478 | uint32_t size; | ||
479 | int skip = 0; | ||
480 | u64 head; | ||
481 | int err; | ||
482 | void *p; | ||
483 | |||
484 | perf_event_ops__fill_defaults(ops); | ||
485 | |||
486 | head = 0; | ||
487 | more: | ||
488 | err = do_read(self->fd, &event, sizeof(struct perf_event_header)); | ||
489 | if (err <= 0) { | ||
490 | if (err == 0) | ||
491 | goto done; | ||
492 | |||
493 | pr_err("failed to read event header\n"); | ||
494 | goto out_err; | ||
495 | } | ||
496 | |||
497 | if (self->header.needs_swap) | ||
498 | perf_event_header__bswap(&event.header); | ||
499 | |||
500 | size = event.header.size; | ||
501 | if (size == 0) | ||
502 | size = 8; | ||
503 | |||
504 | p = &event; | ||
505 | p += sizeof(struct perf_event_header); | ||
506 | |||
507 | err = do_read(self->fd, p, size - sizeof(struct perf_event_header)); | ||
508 | if (err <= 0) { | ||
509 | if (err == 0) { | ||
510 | pr_err("unexpected end of event stream\n"); | ||
511 | goto done; | ||
512 | } | ||
513 | |||
514 | pr_err("failed to read event data\n"); | ||
515 | goto out_err; | ||
516 | } | ||
517 | |||
518 | if (size == 0 || | ||
519 | (skip = perf_session__process_event(self, &event, ops, | ||
520 | 0, head)) < 0) { | ||
521 | dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n", | ||
522 | head, event.header.size, event.header.type); | ||
523 | /* | ||
524 | * assume we lost track of the stream, check alignment, and | ||
525 | * increment a single u64 in the hope to catch on again 'soon'. | ||
526 | */ | ||
527 | if (unlikely(head & 7)) | ||
528 | head &= ~7ULL; | ||
529 | |||
530 | size = 8; | ||
531 | } | ||
532 | |||
533 | head += size; | ||
534 | |||
535 | dump_printf("\n%#Lx [%#x]: event: %d\n", | ||
536 | head, event.header.size, event.header.type); | ||
537 | |||
538 | if (skip > 0) | ||
539 | head += skip; | ||
540 | |||
541 | if (!session_done()) | ||
542 | goto more; | ||
543 | done: | ||
544 | err = 0; | ||
545 | out_err: | ||
546 | return err; | ||
547 | } | ||
548 | |||
379 | int __perf_session__process_events(struct perf_session *self, | 549 | int __perf_session__process_events(struct perf_session *self, |
380 | u64 data_offset, u64 data_size, | 550 | u64 data_offset, u64 data_size, |
381 | u64 file_size, struct perf_event_ops *ops) | 551 | u64 file_size, struct perf_event_ops *ops) |
@@ -499,9 +669,13 @@ out_getcwd_err: | |||
499 | self->cwdlen = strlen(self->cwd); | 669 | self->cwdlen = strlen(self->cwd); |
500 | } | 670 | } |
501 | 671 | ||
502 | err = __perf_session__process_events(self, self->header.data_offset, | 672 | if (!self->fd_pipe) |
503 | self->header.data_size, | 673 | err = __perf_session__process_events(self, |
504 | self->size, ops); | 674 | self->header.data_offset, |
675 | self->header.data_size, | ||
676 | self->size, ops); | ||
677 | else | ||
678 | err = __perf_session__process_pipe_events(self, ops); | ||
505 | out_err: | 679 | out_err: |
506 | return err; | 680 | return err; |
507 | } | 681 | } |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 27f4c2dc715b..0ac14d42dc28 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -27,6 +27,7 @@ struct perf_session { | |||
27 | u64 sample_type; | 27 | u64 sample_type; |
28 | struct ref_reloc_sym ref_reloc_sym; | 28 | struct ref_reloc_sym ref_reloc_sym; |
29 | int fd; | 29 | int fd; |
30 | bool fd_pipe; | ||
30 | int cwdlen; | 31 | int cwdlen; |
31 | char *cwd; | 32 | char *cwd; |
32 | char filename[0]; | 33 | char filename[0]; |
@@ -43,7 +44,11 @@ struct perf_event_ops { | |||
43 | lost, | 44 | lost, |
44 | read, | 45 | read, |
45 | throttle, | 46 | throttle, |
46 | unthrottle; | 47 | unthrottle, |
48 | attr, | ||
49 | event_type, | ||
50 | tracing_data, | ||
51 | build_id; | ||
47 | }; | 52 | }; |
48 | 53 | ||
49 | struct perf_session *perf_session__new(const char *filename, int mode, bool force); | 54 | struct perf_session *perf_session__new(const char *filename, int mode, bool force); |
@@ -92,6 +97,9 @@ static inline struct map * | |||
92 | return map_groups__new_module(&self->kmaps, start, filename); | 97 | return map_groups__new_module(&self->kmaps, start, filename); |
93 | } | 98 | } |
94 | 99 | ||
100 | int do_read(int fd, void *buf, size_t size); | ||
101 | void perf_session__update_sample_type(struct perf_session *self); | ||
102 | |||
95 | #ifdef NO_NEWT_SUPPORT | 103 | #ifdef NO_NEWT_SUPPORT |
96 | static inline int perf_session__browse_hists(struct rb_root *hists __used, | 104 | static inline int perf_session__browse_hists(struct rb_root *hists __used, |
97 | u64 nr_hists __used, | 105 | u64 nr_hists __used, |
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index 5ea8973ad331..30cd9b575953 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c | |||
@@ -154,10 +154,17 @@ static void put_tracing_file(char *file) | |||
154 | free(file); | 154 | free(file); |
155 | } | 155 | } |
156 | 156 | ||
157 | static ssize_t calc_data_size; | ||
158 | |||
157 | static ssize_t write_or_die(const void *buf, size_t len) | 159 | static ssize_t write_or_die(const void *buf, size_t len) |
158 | { | 160 | { |
159 | int ret; | 161 | int ret; |
160 | 162 | ||
163 | if (calc_data_size) { | ||
164 | calc_data_size += len; | ||
165 | return len; | ||
166 | } | ||
167 | |||
161 | ret = write(output_fd, buf, len); | 168 | ret = write(output_fd, buf, len); |
162 | if (ret < 0) | 169 | if (ret < 0) |
163 | die("writing to '%s'", output_file); | 170 | die("writing to '%s'", output_file); |
@@ -526,3 +533,20 @@ int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events) | |||
526 | 533 | ||
527 | return 0; | 534 | return 0; |
528 | } | 535 | } |
536 | |||
537 | ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs, | ||
538 | int nb_events) | ||
539 | { | ||
540 | ssize_t size; | ||
541 | int err = 0; | ||
542 | |||
543 | calc_data_size = 1; | ||
544 | err = read_tracing_data(fd, pattrs, nb_events); | ||
545 | size = calc_data_size - 1; | ||
546 | calc_data_size = 0; | ||
547 | |||
548 | if (err < 0) | ||
549 | return err; | ||
550 | |||
551 | return size; | ||
552 | } | ||
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index 7cd1193918c7..44889c9b5630 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c | |||
@@ -50,14 +50,37 @@ static int long_size; | |||
50 | 50 | ||
51 | static unsigned long page_size; | 51 | static unsigned long page_size; |
52 | 52 | ||
53 | static ssize_t calc_data_size; | ||
54 | |||
55 | static int do_read(int fd, void *buf, int size) | ||
56 | { | ||
57 | int rsize = size; | ||
58 | |||
59 | while (size) { | ||
60 | int ret = read(fd, buf, size); | ||
61 | |||
62 | if (ret <= 0) | ||
63 | return -1; | ||
64 | |||
65 | size -= ret; | ||
66 | buf += ret; | ||
67 | } | ||
68 | |||
69 | return rsize; | ||
70 | } | ||
71 | |||
53 | static int read_or_die(void *data, int size) | 72 | static int read_or_die(void *data, int size) |
54 | { | 73 | { |
55 | int r; | 74 | int r; |
56 | 75 | ||
57 | r = read(input_fd, data, size); | 76 | r = do_read(input_fd, data, size); |
58 | if (r != size) | 77 | if (r <= 0) |
59 | die("reading input file (size expected=%d received=%d)", | 78 | die("reading input file (size expected=%d received=%d)", |
60 | size, r); | 79 | size, r); |
80 | |||
81 | if (calc_data_size) | ||
82 | calc_data_size += r; | ||
83 | |||
61 | return r; | 84 | return r; |
62 | } | 85 | } |
63 | 86 | ||
@@ -82,56 +105,28 @@ static char *read_string(void) | |||
82 | char buf[BUFSIZ]; | 105 | char buf[BUFSIZ]; |
83 | char *str = NULL; | 106 | char *str = NULL; |
84 | int size = 0; | 107 | int size = 0; |
85 | int i; | ||
86 | off_t r; | 108 | off_t r; |
109 | char c; | ||
87 | 110 | ||
88 | for (;;) { | 111 | for (;;) { |
89 | r = read(input_fd, buf, BUFSIZ); | 112 | r = read(input_fd, &c, 1); |
90 | if (r < 0) | 113 | if (r < 0) |
91 | die("reading input file"); | 114 | die("reading input file"); |
92 | 115 | ||
93 | if (!r) | 116 | if (!r) |
94 | die("no data"); | 117 | die("no data"); |
95 | 118 | ||
96 | for (i = 0; i < r; i++) { | 119 | buf[size++] = c; |
97 | if (!buf[i]) | ||
98 | break; | ||
99 | } | ||
100 | if (i < r) | ||
101 | break; | ||
102 | 120 | ||
103 | if (str) { | 121 | if (!c) |
104 | size += BUFSIZ; | 122 | break; |
105 | str = realloc(str, size); | ||
106 | if (!str) | ||
107 | die("malloc of size %d", size); | ||
108 | memcpy(str + (size - BUFSIZ), buf, BUFSIZ); | ||
109 | } else { | ||
110 | size = BUFSIZ; | ||
111 | str = malloc_or_die(size); | ||
112 | memcpy(str, buf, size); | ||
113 | } | ||
114 | } | 123 | } |
115 | 124 | ||
116 | /* trailing \0: */ | 125 | if (calc_data_size) |
117 | i++; | 126 | calc_data_size += size; |
118 | 127 | ||
119 | /* move the file descriptor to the end of the string */ | 128 | str = malloc_or_die(size); |
120 | r = lseek(input_fd, -(r - i), SEEK_CUR); | 129 | memcpy(str, buf, size); |
121 | if (r == (off_t)-1) | ||
122 | die("lseek"); | ||
123 | |||
124 | if (str) { | ||
125 | size += i; | ||
126 | str = realloc(str, size); | ||
127 | if (!str) | ||
128 | die("malloc of size %d", size); | ||
129 | memcpy(str + (size - i), buf, i); | ||
130 | } else { | ||
131 | size = i; | ||
132 | str = malloc_or_die(i); | ||
133 | memcpy(str, buf, i); | ||
134 | } | ||
135 | 130 | ||
136 | return str; | 131 | return str; |
137 | } | 132 | } |
@@ -459,7 +454,7 @@ struct record *trace_read_data(int cpu) | |||
459 | return data; | 454 | return data; |
460 | } | 455 | } |
461 | 456 | ||
462 | void trace_report(int fd) | 457 | ssize_t trace_report(int fd) |
463 | { | 458 | { |
464 | char buf[BUFSIZ]; | 459 | char buf[BUFSIZ]; |
465 | char test[] = { 23, 8, 68 }; | 460 | char test[] = { 23, 8, 68 }; |
@@ -467,6 +462,9 @@ void trace_report(int fd) | |||
467 | int show_version = 0; | 462 | int show_version = 0; |
468 | int show_funcs = 0; | 463 | int show_funcs = 0; |
469 | int show_printk = 0; | 464 | int show_printk = 0; |
465 | ssize_t size; | ||
466 | |||
467 | calc_data_size = 1; | ||
470 | 468 | ||
471 | input_fd = fd; | 469 | input_fd = fd; |
472 | 470 | ||
@@ -499,14 +497,17 @@ void trace_report(int fd) | |||
499 | read_proc_kallsyms(); | 497 | read_proc_kallsyms(); |
500 | read_ftrace_printk(); | 498 | read_ftrace_printk(); |
501 | 499 | ||
500 | size = calc_data_size - 1; | ||
501 | calc_data_size = 0; | ||
502 | |||
502 | if (show_funcs) { | 503 | if (show_funcs) { |
503 | print_funcs(); | 504 | print_funcs(); |
504 | return; | 505 | return size; |
505 | } | 506 | } |
506 | if (show_printk) { | 507 | if (show_printk) { |
507 | print_printk(); | 508 | print_printk(); |
508 | return; | 509 | return size; |
509 | } | 510 | } |
510 | 511 | ||
511 | return; | 512 | return size; |
512 | } | 513 | } |
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 81f2fd20a0ea..1f45d468fd9a 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h | |||
@@ -163,7 +163,7 @@ struct record *trace_read_data(int cpu); | |||
163 | 163 | ||
164 | void parse_set_info(int nr_cpus, int long_sz); | 164 | void parse_set_info(int nr_cpus, int long_sz); |
165 | 165 | ||
166 | void trace_report(int fd); | 166 | ssize_t trace_report(int fd); |
167 | 167 | ||
168 | void *malloc_or_die(unsigned int size); | 168 | void *malloc_or_die(unsigned int size); |
169 | 169 | ||
@@ -259,6 +259,8 @@ void *raw_field_ptr(struct event *event, const char *name, void *data); | |||
259 | unsigned long long eval_flag(const char *flag); | 259 | unsigned long long eval_flag(const char *flag); |
260 | 260 | ||
261 | int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events); | 261 | int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events); |
262 | ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs, | ||
263 | int nb_events); | ||
262 | 264 | ||
263 | /* taken from kernel/trace/trace.h */ | 265 | /* taken from kernel/trace/trace.h */ |
264 | enum trace_flag_type { | 266 | enum trace_flag_type { |