diff options
author | Tom Zanussi <tzanussi@gmail.com> | 2010-05-01 02:41:20 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-02 12:36:56 -0400 |
commit | 454c407ec17a0c63e4023ac0877d687945a7df4a (patch) | |
tree | 1271299a59a89419c0dd4dcbf29b4492b63555ca /tools/perf/util/header.c | |
parent | 789688faef5b3ba78065beaf2f3d6f1c839f74a3 (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.c | 35 |
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; |
722 | out: | 730 | out: |
@@ -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 | ||
784 | static int perf_file_header__read_pipe(struct perf_pipe_file_header *self, | 792 | static 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 | ||
1112 | int event__synthesize_build_id(struct dso *pos, u16 misc, | 1130 | int 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; |