diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt index 88bc3b5197461a099ad2a424f2a64f79abf388d7..5d1a9500277f32535fc8f95ffa12907a3720e6d5 100644 --- a/tools/perf/Documentation/perf-buildid-cache.txt +++ b/tools/perf/Documentation/perf-buildid-cache.txt @@ -8,7 +8,7 @@ perf-buildid-cache - Manage build-id cache. SYNOPSIS -------- [verse] -'perf buildid-list ' +'perf buildid-cache ' DESCRIPTION ----------- @@ -30,4 +30,4 @@ OPTIONS SEE ALSO -------- -linkperf:perf-record[1], linkperf:perf-report[1] +linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-buildid-list[1] diff --git a/tools/perf/Documentation/perf-inject.txt b/tools/perf/Documentation/perf-inject.txt new file mode 100644 index 0000000000000000000000000000000000000000..025630d43cd2331b898b94922be314d980bf3dd1 --- /dev/null +++ b/tools/perf/Documentation/perf-inject.txt @@ -0,0 +1,35 @@ +perf-inject(1) +============== + +NAME +---- +perf-inject - Filter to augment the events stream with additional information + +SYNOPSIS +-------- +[verse] +'perf inject ' + +DESCRIPTION +----------- +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 events stream with additional +information could make use of this facility. + +OPTIONS +------- +-b:: +--build-ids=:: + Inject build-ids into the output stream +-v:: +--verbose:: + Be more verbose. + +SEE ALSO +-------- +linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1] diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 59e981a889089195261e9503d40b65b1bc7b39bd..8e3e47b064cea7ddea4e98f0fb98202b35643632 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -204,7 +204,7 @@ static const char * const report_usage[] = { }; static const struct option options[] = { - OPT_BOOLEAN('b', "inject build-ids", &inject_build_ids, + OPT_BOOLEAN('b', "build-ids", &inject_build_ids, "Inject build-ids into the output stream"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show build ids, etc)"), diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index ac989e9ba8fe067dd1e94a1e2d48ea42ef3b471f..0ff67d1c4752c930719f810e57c226d98f03facc 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -560,11 +560,12 @@ static int __cmd_record(int argc, const char **argv) return err; } - if (raw_samples) { + if (raw_samples && have_tracepoints(attrs, nr_counters)) { perf_header__set_feat(&session->header, HEADER_TRACE_INFO); } else { for (i = 0; i < nr_counters; i++) { - if (attrs[i].sample_type & PERF_SAMPLE_RAW) { + if (attrs[i].sample_type & PERF_SAMPLE_RAW && + attrs[i].type == PERF_TYPE_TRACEPOINT) { perf_header__set_feat(&session->header, HEADER_TRACE_INFO); break; } @@ -662,19 +663,25 @@ static int __cmd_record(int argc, const char **argv) return err; } - err = event__synthesize_tracing_data(output, attrs, - nr_counters, - process_synthesized_event, - session); - /* - * FIXME err <= 0 here actually means that there were no tracepoints - * so its not really an error, just that we don't need to synthesize - * anything. - * We really have to return this more properly and also propagate - * errors that now are calling die() - */ - if (err > 0) + if (have_tracepoints(attrs, nr_counters)) { + /* + * FIXME err <= 0 here actually means that + * there were no tracepoints so its not really + * an error, just that we don't need to + * synthesize anything. We really have to + * return this more properly and also + * propagate errors that now are calling die() + */ + err = event__synthesize_tracing_data(output, attrs, + nr_counters, + process_synthesized_event, + session); + if (err <= 0) { + pr_err("Couldn't record tracing data.\n"); + return err; + } advance_output(err); + } } machine = perf_session__find_host_machine(session); diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt index 80a1a446ce35af4440bb3db2a53356e14f6e4881..949d77fc0b9718d812a8906883b7a89ef99c49f0 100644 --- a/tools/perf/command-list.txt +++ b/tools/perf/command-list.txt @@ -8,6 +8,7 @@ perf-bench mainporcelain common perf-buildid-cache mainporcelain common perf-buildid-list mainporcelain common perf-diff mainporcelain common +perf-inject mainporcelain common perf-list mainporcelain common perf-sched mainporcelain common perf-record mainporcelain common diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 1757b0ffeaa97a29812b4727d451305110c9ba3f..2477270c1d3fe372dcdb6cf840356a2e3846a8fd 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -713,6 +713,7 @@ int event__parse_sample(event_t *event, u64 type, struct sample_data *data) array++; } + data->id = -1ULL; if (type & PERF_SAMPLE_ID) { data->id = *array; array++; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 79da0e50ef8ff1a7456eb4757c94c7629f168fbb..8847bec64c54119fc0e006dbd6350b231203dbd9 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -436,7 +436,6 @@ static int perf_header__adds_write(struct perf_header *self, int fd) trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset; } - if (perf_header__has_feat(self, HEADER_BUILD_ID)) { struct perf_file_section *buildid_sec; @@ -923,6 +922,14 @@ perf_header__find_attr(u64 id, struct perf_header *header) { int i; + /* + * We set id to -1 if the data file doesn't contain sample + * ids. Check for this and avoid walking through the entire + * list of ids which may be large. + */ + if (id == -1ULL) + return NULL; + for (i = 0; i < header->attrs; i++) { struct perf_header_attr *attr = header->attr[i]; int j; diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index b8c1f64bc9351ac7f889340c20eb7755614f5227..fc4ab3fe877a22d191450a6bc4c75118cf71901d 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -13,6 +13,7 @@ struct tracepoint_path { }; extern struct tracepoint_path *tracepoint_id_to_path(u64 config); +extern bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events); extern int nr_counters; diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index 30cd9b57595301ed3793f84f96b6ce6b279c8a40..0a1fb9d4f3b60b75edd8b00071ec9ef1062e8cea 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -487,6 +487,11 @@ get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events) return nr_tracepoints > 0 ? path.next : NULL; } +bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events) +{ + return get_tracepoints_path(pattrs, nb_events) ? true : false; +} + int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events) { char buf[BUFSIZ];