summaryrefslogtreecommitdiff
path: root/tools/perf/builtin-inject.c
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2021-07-20 01:31:52 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2021-08-02 16:14:34 +0300
commitc3a057dc3aa9979ce6dc350e05eb2e4c021432cd (patch)
tree529d39004afcda9a59b78f2a77564835f4fe9fd6 /tools/perf/builtin-inject.c
parentfea20d66f90cdbdc7dccf1fa001d40e084984e55 (diff)
downloadlinux-c3a057dc3aa9979ce6dc350e05eb2e4c021432cd.tar.xz
perf inject: Fix output from a file to a pipe
When the input is a regular file but the output is a pipe, it should write a pipe header. But just repiping would write a portion of the existing header which is different in 'size' value. So we need to prevent it and write a new pipe header along with other information like event attributes and features. This can handle something like this: # perf record -a -B sleep 1 # perf inject -b -i perf.data | perf report -i - Factor out perf_event__synthesize_for_pipe() to be shared between perf record and inject. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Acked-by: Jiri Olsa <jolsa@redhat.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lore.kernel.org/lkml/20210719223153.1618812-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-inject.c')
-rw-r--r--tools/perf/builtin-inject.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index f9af24350f61..6ad191e731fc 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -919,6 +919,7 @@ int cmd_inject(int argc, const char **argv)
.use_stdio = true,
};
int ret;
+ bool repipe = true;
struct option options[] = {
OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
@@ -993,10 +994,18 @@ int cmd_inject(int argc, const char **argv)
}
data.path = inject.input_name;
- if (!strcmp(inject.input_name, "-") || inject.output.is_pipe)
+ if (!strcmp(inject.input_name, "-") || inject.output.is_pipe) {
inject.is_pipe = true;
+ /*
+ * Do not repipe header when input is a regular file
+ * since either it can rewrite the header at the end
+ * or write a new pipe header.
+ */
+ if (strcmp(inject.input_name, "-"))
+ repipe = false;
+ }
- inject.session = __perf_session__new(&data, inject.is_pipe,
+ inject.session = __perf_session__new(&data, repipe,
perf_data__fd(&inject.output),
&inject.tool);
if (IS_ERR(inject.session)) {
@@ -1007,6 +1016,21 @@ int cmd_inject(int argc, const char **argv)
if (zstd_init(&(inject.session->zstd_data), 0) < 0)
pr_warning("Decompression initialization failed.\n");
+ if (!data.is_pipe && inject.output.is_pipe) {
+ ret = perf_header__write_pipe(perf_data__fd(&inject.output));
+ if (ret < 0) {
+ pr_err("Couldn't write a new pipe header.\n");
+ goto out_delete;
+ }
+
+ ret = perf_event__synthesize_for_pipe(&inject.tool,
+ inject.session,
+ &inject.output,
+ perf_event__repipe);
+ if (ret < 0)
+ goto out_delete;
+ }
+
if (inject.build_ids && !inject.build_id_all) {
/*
* to make sure the mmap records are ordered correctly