lkml.org 
[lkml]   [2009]   [Oct]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] perf tools: Add a new generic section in perf.data
Date
Add a new generic section into the perf.data file. This section simply
stands as a set of subsections that can be added once it is needed.
This section is versioned so that it's flexible enough to carry a
backward and forward compatibility with other versions of this generic
section.

For now it only handles the trace_info subsection.

This whole change is backward compatible with .32 perf.data but
not with the current development version for .33

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
tools/perf/util/header.c | 104 ++++++++++++++++++++++++++++++++--------------
tools/perf/util/header.h | 4 +-
2 files changed, 75 insertions(+), 33 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 9aae360..d11c467 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -64,8 +64,8 @@ struct perf_header *perf_header__new(void)

self->data_offset = 0;
self->data_size = 0;
- self->trace_info_offset = 0;
- self->trace_info_size = 0;
+ self->adds_offset = 0;
+ self->adds_size = 0;

return self;
}
@@ -142,6 +142,15 @@ struct perf_file_attr {
struct perf_file_section ids;
};

+/*
+ * Version 0: contains trace_info section only
+ */
+struct perf_file_additionals {
+ u64 version;
+ struct perf_file_section trace_info;
+};
+
+
struct perf_file_header {
u64 magic;
u64 size;
@@ -149,7 +158,7 @@ struct perf_file_header {
struct perf_file_section attrs;
struct perf_file_section data;
struct perf_file_section event_types;
- struct perf_file_section trace_info;
+ struct perf_file_section adds;
};

static int trace_info;
@@ -172,6 +181,34 @@ static void do_write(int fd, void *buf, size_t size)
}
}

+static void perf_header__adds_write(struct perf_header *self, int fd)
+{
+ struct perf_file_additionals adds = {
+ .version = 0,
+ .trace_info = {
+ .offset = 0,
+ .size = 0,
+ },
+ };
+
+ self->adds_offset = lseek(fd, 0, SEEK_CUR);
+ lseek(fd, sizeof(adds), SEEK_CUR);
+
+ if (trace_info) {
+ adds.trace_info.offset = lseek(fd, 0, SEEK_CUR);
+ read_tracing_data(fd, attrs, nr_counters);
+ adds.trace_info.size = lseek(fd, 0, SEEK_CUR) -
+ adds.trace_info.offset;
+ }
+
+ self->adds_size = lseek(fd, 0, SEEK_CUR) - self->adds_offset;
+
+ /* Write adds headers */
+ lseek(fd, self->adds_offset, SEEK_SET);
+ do_write(fd, &adds, sizeof(adds));
+ lseek(fd, self->adds_offset + self->adds_size, SEEK_SET);
+};
+
void perf_header__write(struct perf_header *self, int fd)
{
struct perf_file_header f_header;
@@ -210,23 +247,7 @@ void perf_header__write(struct perf_header *self, int fd)
if (events)
do_write(fd, events, self->event_size);

- if (trace_info) {
- static int trace_info_written;
-
- /*
- * Write it only once
- */
- if (!trace_info_written) {
- self->trace_info_offset = lseek(fd, 0, SEEK_CUR);
- read_tracing_data(fd, attrs, nr_counters);
- self->trace_info_size = lseek(fd, 0, SEEK_CUR) -
- self->trace_info_offset;
- trace_info_written = 1;
- } else {
- lseek(fd, self->trace_info_offset +
- self->trace_info_size, SEEK_SET);
- }
- }
+ perf_header__adds_write(self, fd);

self->data_offset = lseek(fd, 0, SEEK_CUR);

@@ -246,9 +267,9 @@ void perf_header__write(struct perf_header *self, int fd)
.offset = self->event_offset,
.size = self->event_size,
},
- .trace_info = {
- .offset = self->trace_info_offset,
- .size = self->trace_info_size,
+ .adds = {
+ .offset = self->adds_offset,
+ .size = self->adds_size,
},
};

@@ -274,6 +295,30 @@ static void do_read(int fd, void *buf, size_t size)
}
}

+/*
+ * Version 0: only need to read trace info
+ */
+static void perf_header__adds_read(struct perf_header *self, int fd)
+{
+ struct perf_file_additionals adds;
+
+ /* Previous versions don't have adds section */
+ if (!self->adds_size)
+ return;
+
+ lseek(fd, self->adds_offset, SEEK_SET);
+ do_read(fd, &adds, sizeof(adds));
+
+ /*
+ * Every adds section versions need to handle at least
+ * the trace info
+ */
+ if (adds.trace_info.size) {
+ lseek(fd, adds.trace_info.offset, SEEK_SET);
+ trace_report(fd);
+ }
+};
+
struct perf_header *perf_header__read(int fd)
{
struct perf_header *self = perf_header__new();
@@ -292,8 +337,8 @@ struct perf_header *perf_header__read(int fd)

if (f_header.size != sizeof(f_header)) {
/* Support the previous format */
- if (f_header.size == offsetof(typeof(f_header), trace_info))
- f_header.trace_info.size = 0;
+ if (f_header.size == offsetof(typeof(f_header), adds))
+ f_header.adds.size = 0;
else
die("incompatible file format");
}
@@ -330,13 +375,10 @@ struct perf_header *perf_header__read(int fd)
event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
}

- self->trace_info_offset = f_header.trace_info.offset;
- self->trace_info_size = f_header.trace_info.size;
+ self->adds_offset = f_header.adds.offset;
+ self->adds_size = f_header.adds.size;

- if (self->trace_info_size) {
- lseek(fd, self->trace_info_offset, SEEK_SET);
- trace_report(fd);
- }
+ perf_header__adds_read(self, fd);

self->event_offset = f_header.event_types.offset;
self->event_size = f_header.event_types.size;
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 30aee51..8198022 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -21,8 +21,8 @@ struct perf_header {
u64 data_size;
u64 event_offset;
u64 event_size;
- u64 trace_info_offset;
- u64 trace_info_size;
+ u64 adds_offset;
+ u64 adds_size;
};

struct perf_header *perf_header__read(int fd);
--
1.6.2.3


\
 
 \ /
  Last update: 2009-10-15 23:15    [W:0.060 / U:0.640 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site