aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/header.c
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2010-05-01 02:41:20 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-05-02 12:36:56 -0400
commit454c407ec17a0c63e4023ac0877d687945a7df4a (patch)
tree1271299a59a89419c0dd4dcbf29b4492b63555ca /tools/perf/util/header.c
parent789688faef5b3ba78065beaf2f3d6f1c839f74a3 (diff)
perf: add perf-inject builtin
Currently, perf 'live mode' writes build-ids at the end of the session, which isn't actually useful for processing live mode events. What would be better would be to have the build-ids sent before any of the samples that reference them, which can be done by processing the event stream and retrieving the build-ids on the first hit. Doing that in perf-record itself, however, is off-limits. This patch introduces perf-inject, which does the same job while leaving perf-record untouched. Normal mode perf still records the build-ids at the end of the session as it should, but for live mode, perf-inject can be injected in between the record and report steps e.g.: perf record -o - ./hackbench 10 | perf inject -v -b | perf report -v -i - perf-inject reads a perf-record event stream and repipes it to stdout. At any point the processing code can inject other events into the event stream - in this case build-ids (-b option) are read and injected as needed into the event stream. Build-ids are just the first user of perf-inject - potentially anything that needs userspace processing to augment the trace stream with additional information could make use of this facility. Cc: Ingo Molnar <mingo@elte.hu> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Frédéric Weisbecker <fweisbec@gmail.com> LKML-Reference: <1272696080-16435-3-git-send-email-tzanussi@gmail.com> Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r--tools/perf/util/header.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 2d1d97e0746d..79da0e50ef8f 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -713,10 +713,18 @@ static int __event_process_build_id(struct build_id_event *bev,
713 713
714 dso = __dsos__findnew(head, filename); 714 dso = __dsos__findnew(head, filename);
715 if (dso != NULL) { 715 if (dso != NULL) {
716 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
717
716 dso__set_build_id(dso, &bev->build_id); 718 dso__set_build_id(dso, &bev->build_id);
717 if (filename[0] == '[') 719
718 dso->kernel = dso_type; 720 if (filename[0] == '[')
719 } 721 dso->kernel = dso_type;
722
723 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
724 sbuild_id);
725 pr_debug("build id event received for %s: %s\n",
726 dso->long_name, sbuild_id);
727 }
720 728
721 err = 0; 729 err = 0;
722out: 730out:
@@ -767,7 +775,7 @@ static int perf_file_section__process(struct perf_file_section *self,
767 775
768 switch (feat) { 776 switch (feat) {
769 case HEADER_TRACE_INFO: 777 case HEADER_TRACE_INFO:
770 trace_report(fd); 778 trace_report(fd, false);
771 break; 779 break;
772 780
773 case HEADER_BUILD_ID: 781 case HEADER_BUILD_ID:
@@ -782,12 +790,16 @@ static int perf_file_section__process(struct perf_file_section *self,
782} 790}
783 791
784static int perf_file_header__read_pipe(struct perf_pipe_file_header *self, 792static int perf_file_header__read_pipe(struct perf_pipe_file_header *self,
785 struct perf_header *ph, int fd) 793 struct perf_header *ph, int fd,
794 bool repipe)
786{ 795{
787 if (do_read(fd, self, sizeof(*self)) <= 0 || 796 if (do_read(fd, self, sizeof(*self)) <= 0 ||
788 memcmp(&self->magic, __perf_magic, sizeof(self->magic))) 797 memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
789 return -1; 798 return -1;
790 799
800 if (repipe && do_write(STDOUT_FILENO, self, sizeof(*self)) < 0)
801 return -1;
802
791 if (self->size != sizeof(*self)) { 803 if (self->size != sizeof(*self)) {
792 u64 size = bswap_64(self->size); 804 u64 size = bswap_64(self->size);
793 805
@@ -805,7 +817,8 @@ static int perf_header__read_pipe(struct perf_session *session, int fd)
805 struct perf_header *self = &session->header; 817 struct perf_header *self = &session->header;
806 struct perf_pipe_file_header f_header; 818 struct perf_pipe_file_header f_header;
807 819
808 if (perf_file_header__read_pipe(&f_header, self, fd) < 0) { 820 if (perf_file_header__read_pipe(&f_header, self, fd,
821 session->repipe) < 0) {
809 pr_debug("incompatible file format\n"); 822 pr_debug("incompatible file format\n");
810 return -EINVAL; 823 return -EINVAL;
811 } 824 }
@@ -1096,12 +1109,17 @@ int event__process_tracing_data(event_t *self,
1096 lseek(session->fd, offset + sizeof(struct tracing_data_event), 1109 lseek(session->fd, offset + sizeof(struct tracing_data_event),
1097 SEEK_SET); 1110 SEEK_SET);
1098 1111
1099 size_read = trace_report(session->fd); 1112 size_read = trace_report(session->fd, session->repipe);
1100 1113
1101 padding = ALIGN(size_read, sizeof(u64)) - size_read; 1114 padding = ALIGN(size_read, sizeof(u64)) - size_read;
1102 1115
1103 if (read(session->fd, buf, padding) < 0) 1116 if (read(session->fd, buf, padding) < 0)
1104 die("reading input file"); 1117 die("reading input file");
1118 if (session->repipe) {
1119 int retw = write(STDOUT_FILENO, buf, padding);
1120 if (retw <= 0 || retw != padding)
1121 die("repiping tracing data padding");
1122 }
1105 1123
1106 if (size_read + padding != size) 1124 if (size_read + padding != size)
1107 die("tracing data size mismatch"); 1125 die("tracing data size mismatch");
@@ -1110,7 +1128,8 @@ int event__process_tracing_data(event_t *self,
1110} 1128}
1111 1129
1112int event__synthesize_build_id(struct dso *pos, u16 misc, 1130int event__synthesize_build_id(struct dso *pos, u16 misc,
1113 event__handler_t process, struct machine *machine, 1131 event__handler_t process,
1132 struct machine *machine,
1114 struct perf_session *session) 1133 struct perf_session *session)
1115{ 1134{
1116 event_t ev; 1135 event_t ev;