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>
This commit is contained in:
committed by
Arnaldo Carvalho de Melo
parent
789688faef
commit
454c407ec1
@@ -713,10 +713,18 @@ static int __event_process_build_id(struct build_id_event *bev,
|
||||
|
||||
dso = __dsos__findnew(head, filename);
|
||||
if (dso != NULL) {
|
||||
char sbuild_id[BUILD_ID_SIZE * 2 + 1];
|
||||
|
||||
dso__set_build_id(dso, &bev->build_id);
|
||||
if (filename[0] == '[')
|
||||
dso->kernel = dso_type;
|
||||
}
|
||||
|
||||
if (filename[0] == '[')
|
||||
dso->kernel = dso_type;
|
||||
|
||||
build_id__sprintf(dso->build_id, sizeof(dso->build_id),
|
||||
sbuild_id);
|
||||
pr_debug("build id event received for %s: %s\n",
|
||||
dso->long_name, sbuild_id);
|
||||
}
|
||||
|
||||
err = 0;
|
||||
out:
|
||||
@@ -767,7 +775,7 @@ static int perf_file_section__process(struct perf_file_section *self,
|
||||
|
||||
switch (feat) {
|
||||
case HEADER_TRACE_INFO:
|
||||
trace_report(fd);
|
||||
trace_report(fd, false);
|
||||
break;
|
||||
|
||||
case HEADER_BUILD_ID:
|
||||
@@ -782,12 +790,16 @@ static int perf_file_section__process(struct perf_file_section *self,
|
||||
}
|
||||
|
||||
static int perf_file_header__read_pipe(struct perf_pipe_file_header *self,
|
||||
struct perf_header *ph, int fd)
|
||||
struct perf_header *ph, int fd,
|
||||
bool repipe)
|
||||
{
|
||||
if (do_read(fd, self, sizeof(*self)) <= 0 ||
|
||||
memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
|
||||
return -1;
|
||||
|
||||
if (repipe && do_write(STDOUT_FILENO, self, sizeof(*self)) < 0)
|
||||
return -1;
|
||||
|
||||
if (self->size != sizeof(*self)) {
|
||||
u64 size = bswap_64(self->size);
|
||||
|
||||
@@ -805,7 +817,8 @@ static int perf_header__read_pipe(struct perf_session *session, int fd)
|
||||
struct perf_header *self = &session->header;
|
||||
struct perf_pipe_file_header f_header;
|
||||
|
||||
if (perf_file_header__read_pipe(&f_header, self, fd) < 0) {
|
||||
if (perf_file_header__read_pipe(&f_header, self, fd,
|
||||
session->repipe) < 0) {
|
||||
pr_debug("incompatible file format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1096,12 +1109,17 @@ int event__process_tracing_data(event_t *self,
|
||||
lseek(session->fd, offset + sizeof(struct tracing_data_event),
|
||||
SEEK_SET);
|
||||
|
||||
size_read = trace_report(session->fd);
|
||||
size_read = trace_report(session->fd, session->repipe);
|
||||
|
||||
padding = ALIGN(size_read, sizeof(u64)) - size_read;
|
||||
|
||||
if (read(session->fd, buf, padding) < 0)
|
||||
die("reading input file");
|
||||
if (session->repipe) {
|
||||
int retw = write(STDOUT_FILENO, buf, padding);
|
||||
if (retw <= 0 || retw != padding)
|
||||
die("repiping tracing data padding");
|
||||
}
|
||||
|
||||
if (size_read + padding != size)
|
||||
die("tracing data size mismatch");
|
||||
@@ -1110,7 +1128,8 @@ int event__process_tracing_data(event_t *self,
|
||||
}
|
||||
|
||||
int event__synthesize_build_id(struct dso *pos, u16 misc,
|
||||
event__handler_t process, struct machine *machine,
|
||||
event__handler_t process,
|
||||
struct machine *machine,
|
||||
struct perf_session *session)
|
||||
{
|
||||
event_t ev;
|
||||
|
Reference in New Issue
Block a user