Commit 03456a15 authored by Frederic Weisbecker's avatar Frederic Weisbecker Committed by Ingo Molnar

perf tools: Merge trace.info content into perf.data

This drops the trace.info file and move its contents into the
common perf.data file.

This is done by creating a new trace_info section into this file. A
user of perf headers needs to call perf_header__set_trace_info() to
save the trace meta informations into the perf.data file.

A file created by perf after his patch is unsupported by previous
version because the size of the headers have increased.

That said, it's two new fields that have been added in the end of
the headers, and those could be ignored by previous versions if
they just handled the dynamic header size and then ignore the
unknow part. The offsets guarantee the compatibility. We'll do a
-stable fix for that.

But current previous versions handle the header size using its
static size, not dynamic, then it's not backward compatible with
trace records.
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <20091006213643.GA5343@nowhere>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent b209aa1f
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "util/header.h" #include "util/header.h"
#include "util/event.h" #include "util/event.h"
#include "util/debug.h" #include "util/debug.h"
#include "util/trace-event.h"
#include <unistd.h> #include <unistd.h>
#include <sched.h> #include <sched.h>
...@@ -566,17 +565,17 @@ static int __cmd_record(int argc, const char **argv) ...@@ -566,17 +565,17 @@ static int __cmd_record(int argc, const char **argv)
else else
header = perf_header__new(); header = perf_header__new();
if (raw_samples) { if (raw_samples) {
read_tracing_data(attrs, nr_counters); perf_header__set_trace_info();
} else { } else {
for (i = 0; i < nr_counters; i++) { for (i = 0; i < nr_counters; i++) {
if (attrs[i].sample_type & PERF_SAMPLE_RAW) { if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
read_tracing_data(attrs, nr_counters); perf_header__set_trace_info();
break; break;
} }
} }
} }
atexit(atexit_header); atexit(atexit_header);
if (!system_wide) { if (!system_wide) {
......
...@@ -1634,7 +1634,6 @@ static int read_events(void) ...@@ -1634,7 +1634,6 @@ static int read_events(void)
uint32_t size; uint32_t size;
char *buf; char *buf;
trace_report();
register_idle_thread(&threads, &last_match); register_idle_thread(&threads, &last_match);
input = open(input_name, O_RDONLY); input = open(input_name, O_RDONLY);
......
...@@ -149,7 +149,6 @@ static int __cmd_trace(void) ...@@ -149,7 +149,6 @@ static int __cmd_trace(void)
uint32_t size; uint32_t size;
char *buf; char *buf;
trace_report();
register_idle_thread(&threads, &last_match); register_idle_thread(&threads, &last_match);
input = open(input_name, O_RDONLY); input = open(input_name, O_RDONLY);
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "util.h" #include "util.h"
#include "header.h" #include "header.h"
#include "../perf.h"
#include "trace-event.h"
/* /*
* Create new perf.data header attribute: * Create new perf.data header attribute:
...@@ -62,6 +64,8 @@ struct perf_header *perf_header__new(void) ...@@ -62,6 +64,8 @@ struct perf_header *perf_header__new(void)
self->data_offset = 0; self->data_offset = 0;
self->data_size = 0; self->data_size = 0;
self->trace_info_offset = 0;
self->trace_info_size = 0;
return self; return self;
} }
...@@ -145,8 +149,16 @@ struct perf_file_header { ...@@ -145,8 +149,16 @@ struct perf_file_header {
struct perf_file_section attrs; struct perf_file_section attrs;
struct perf_file_section data; struct perf_file_section data;
struct perf_file_section event_types; struct perf_file_section event_types;
struct perf_file_section trace_info;
}; };
static int trace_info;
void perf_header__set_trace_info(void)
{
trace_info = 1;
}
static void do_write(int fd, void *buf, size_t size) static void do_write(int fd, void *buf, size_t size)
{ {
while (size) { while (size) {
...@@ -198,6 +210,23 @@ void perf_header__write(struct perf_header *self, int fd) ...@@ -198,6 +210,23 @@ void perf_header__write(struct perf_header *self, int fd)
if (events) if (events)
do_write(fd, events, self->event_size); 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);
}
}
self->data_offset = lseek(fd, 0, SEEK_CUR); self->data_offset = lseek(fd, 0, SEEK_CUR);
...@@ -217,6 +246,10 @@ void perf_header__write(struct perf_header *self, int fd) ...@@ -217,6 +246,10 @@ void perf_header__write(struct perf_header *self, int fd)
.offset = self->event_offset, .offset = self->event_offset,
.size = self->event_size, .size = self->event_size,
}, },
.trace_info = {
.offset = self->trace_info_offset,
.size = self->trace_info_size,
},
}; };
lseek(fd, 0, SEEK_SET); lseek(fd, 0, SEEK_SET);
...@@ -290,6 +323,15 @@ struct perf_header *perf_header__read(int fd) ...@@ -290,6 +323,15 @@ struct perf_header *perf_header__read(int fd)
do_read(fd, events, f_header.event_types.size); do_read(fd, events, f_header.event_types.size);
event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); 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;
if (self->trace_info_size) {
lseek(fd, self->trace_info_offset, SEEK_SET);
trace_report(fd);
}
self->event_offset = f_header.event_types.offset; self->event_offset = f_header.event_types.offset;
self->event_size = f_header.event_types.size; self->event_size = f_header.event_types.size;
......
...@@ -21,6 +21,8 @@ struct perf_header { ...@@ -21,6 +21,8 @@ struct perf_header {
u64 data_size; u64 data_size;
u64 event_offset; u64 event_offset;
u64 event_size; u64 event_size;
u64 trace_info_offset;
u64 trace_info_size;
}; };
struct perf_header *perf_header__read(int fd); struct perf_header *perf_header__read(int fd);
...@@ -40,7 +42,7 @@ void perf_header_attr__add_id(struct perf_header_attr *self, u64 id); ...@@ -40,7 +42,7 @@ void perf_header_attr__add_id(struct perf_header_attr *self, u64 id);
u64 perf_header__sample_type(struct perf_header *header); u64 perf_header__sample_type(struct perf_header *header);
struct perf_event_attr * struct perf_event_attr *
perf_header__find_attr(u64 id, struct perf_header *header); perf_header__find_attr(u64 id, struct perf_header *header);
void perf_header__set_trace_info(void);
struct perf_header *perf_header__new(void); struct perf_header *perf_header__new(void);
......
...@@ -496,14 +496,12 @@ get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events) ...@@ -496,14 +496,12 @@ get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events)
return path.next; return path.next;
} }
void read_tracing_data(struct perf_event_attr *pattrs, int nb_events) void read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events)
{ {
char buf[BUFSIZ]; char buf[BUFSIZ];
struct tracepoint_path *tps; struct tracepoint_path *tps;
output_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); output_fd = fd;
if (output_fd < 0)
die("creating file '%s'", output_file);
buf[0] = 23; buf[0] = 23;
buf[1] = 8; buf[1] = 8;
......
...@@ -458,9 +458,8 @@ struct record *trace_read_data(int cpu) ...@@ -458,9 +458,8 @@ struct record *trace_read_data(int cpu)
return data; return data;
} }
void trace_report(void) void trace_report(int fd)
{ {
const char *input_file = "trace.info";
char buf[BUFSIZ]; char buf[BUFSIZ];
char test[] = { 23, 8, 68 }; char test[] = { 23, 8, 68 };
char *version; char *version;
...@@ -468,9 +467,7 @@ void trace_report(void) ...@@ -468,9 +467,7 @@ void trace_report(void)
int show_funcs = 0; int show_funcs = 0;
int show_printk = 0; int show_printk = 0;
input_fd = open(input_file, O_RDONLY); input_fd = fd;
if (input_fd < 0)
die("opening '%s'\n", input_file);
read_or_die(buf, 3); read_or_die(buf, 3);
if (memcmp(buf, test, 3) != 0) if (memcmp(buf, test, 3) != 0)
......
...@@ -158,7 +158,7 @@ struct record *trace_read_data(int cpu); ...@@ -158,7 +158,7 @@ struct record *trace_read_data(int cpu);
void parse_set_info(int nr_cpus, int long_sz); void parse_set_info(int nr_cpus, int long_sz);
void trace_report(void); void trace_report(int fd);
void *malloc_or_die(unsigned int size); void *malloc_or_die(unsigned int size);
...@@ -244,6 +244,6 @@ unsigned long long ...@@ -244,6 +244,6 @@ unsigned long long
raw_field_value(struct event *event, const char *name, void *data); raw_field_value(struct event *event, const char *name, void *data);
void *raw_field_ptr(struct event *event, const char *name, void *data); void *raw_field_ptr(struct event *event, const char *name, void *data);
void read_tracing_data(struct perf_event_attr *pattrs, int nb_events); void read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events);
#endif /* __PERF_TRACE_EVENTS_H */ #endif /* __PERF_TRACE_EVENTS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment