summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/header.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2011-10-20 15:59:43 +0200
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-10-20 12:41:42 -0200
commit29208e573a9409ee56599cc0157f31b42c7a0235 (patch)
treed3fab38970ba13235c630f4ab4f70edc217ac628 /tools/perf/util/header.c
parentcc02c921a01794f85ad53b396133f11d4ddd17ff (diff)
downloadop-kernel-dev-29208e573a9409ee56599cc0157f31b42c7a0235.zip
op-kernel-dev-29208e573a9409ee56599cc0157f31b42c7a0235.tar.gz
perf tools: Fix tracing info recording
Fixing the way the tracing information is stored within record command. The current implementation is causing issues for pipe output. Following commands fail currently: perf script syscall-counts ls perf record -e syscalls:sys_exit_read ls | ./perf report -i - The tracing information is part of the perf data file. It contains several files from within the tracing debugfs and procs directories. Beside some static header files, for each tracing event the format file is added. The /proc/kallsyms file is also added. The tracing data are stored with preceeding size. This is causing some dificulties for pipe output, since there's no way to tell debugfs/proc file size before reading it. So, for pipe output, all the debugfs files were read twice. Once to get the overall size and once to store the content itself. This can cause problem in case any of these file changed, within the storage time. To fix this behaviour and ensure the integrity of the tracing data, we: - read debugfs/proc file into the temp file - get temp file size and dump it to the pipe - dump the temp file contents to the pipe Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Neil Horman <nhorman@tuxdriver.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/20111020135943.GD2092@jolsa.brq.redhat.com Signed-off-by: Jiri Olsa <jolsa@redhat.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.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 6a9c041..76c0b2c 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2218,15 +2218,29 @@ int perf_event__synthesize_tracing_data(int fd, struct perf_evlist *evlist,
struct perf_session *session __unused)
{
union perf_event ev;
+ struct tracing_data *tdata;
ssize_t size = 0, aligned_size = 0, padding;
int err __used = 0;
+ /*
+ * We are going to store the size of the data followed
+ * by the data contents. Since the fd descriptor is a pipe,
+ * we cannot seek back to store the size of the data once
+ * we know it. Instead we:
+ *
+ * - write the tracing data to the temp file
+ * - get/write the data size to pipe
+ * - write the tracing data from the temp file
+ * to the pipe
+ */
+ tdata = tracing_data_get(&evlist->entries, fd, true);
+ if (!tdata)
+ return -1;
+
memset(&ev, 0, sizeof(ev));
ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
- size = read_tracing_data_size(fd, &evlist->entries);
- if (size <= 0)
- return size;
+ size = tdata->size;
aligned_size = ALIGN(size, sizeof(u64));
padding = aligned_size - size;
ev.tracing_data.header.size = sizeof(ev.tracing_data);
@@ -2234,7 +2248,12 @@ int perf_event__synthesize_tracing_data(int fd, struct perf_evlist *evlist,
process(&ev, NULL, session);
- err = read_tracing_data(fd, &evlist->entries);
+ /*
+ * The put function will copy all the tracing data
+ * stored in temp file to the pipe.
+ */
+ tracing_data_put(tdata);
+
write_padded(fd, NULL, 0, padding);
return aligned_size;
OpenPOWER on IntegriCloud