aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2009-09-12 01:52:51 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-19 05:42:11 -0400
commit8755a8f27ae590dde225f9005ee18c6d9c4c6d78 (patch)
tree1a86744bf0f5ee71bc5f2d0c29f86f9721aa6f4a /tools/perf
parent393b2ad8c757ba3ccd2a99ca5bbcd6db4d3fa53d (diff)
perf: Store trace event name/id pairs in perf.data
The trace event name<->id mapping is dynamic for each kernel compile. In order for perf.data to be useable outside the actual system, we thus need to store a table of this mapping for later use. This patch adds this table to perf.data, and provides helper functions for lookup up fields from this table. To avoid mistakes, lookup-from-table is kept completely seprate from lookup-from-local-debugfs. Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <20090912130405.6960d099@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/header.c59
-rw-r--r--tools/perf/util/header.h6
-rw-r--r--tools/perf/util/parse-events.c25
3 files changed, 90 insertions, 0 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ec4d4c2f9522..ef9114583994 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -86,6 +86,44 @@ void perf_header__add_attr(struct perf_header *self,
86 self->attr[pos] = attr; 86 self->attr[pos] = attr;
87} 87}
88 88
89struct perf_trace_event_type {
90 u64 event_id;
91 char name[64];
92};
93
94static int event_count;
95static struct perf_trace_event_type *events;
96
97void perf_header__push_event(u64 id, const char *name)
98{
99 if (strlen(name) > 64)
100 printf("Event %s will be truncated\n", name);
101
102 if (!events) {
103 events = malloc(sizeof(struct perf_trace_event_type));
104 if (!events)
105 die("nomem");
106 } else {
107 events = realloc(events, (event_count + 1) * sizeof(struct perf_trace_event_type));
108 if (!events)
109 die("nomem");
110 }
111 memset(&events[event_count], 0, sizeof(struct perf_trace_event_type));
112 events[event_count].event_id = id;
113 strncpy(events[event_count].name, name, 63);
114 event_count++;
115}
116
117char *perf_header__find_event(u64 id)
118{
119 int i;
120 for (i = 0 ; i < event_count; i++) {
121 if (events[i].event_id == id)
122 return events[i].name;
123 }
124 return NULL;
125}
126
89static const char *__perf_magic = "PERFFILE"; 127static const char *__perf_magic = "PERFFILE";
90 128
91#define PERF_MAGIC (*(u64 *)__perf_magic) 129#define PERF_MAGIC (*(u64 *)__perf_magic)
@@ -106,6 +144,7 @@ struct perf_file_header {
106 u64 attr_size; 144 u64 attr_size;
107 struct perf_file_section attrs; 145 struct perf_file_section attrs;
108 struct perf_file_section data; 146 struct perf_file_section data;
147 struct perf_file_section event_types;
109}; 148};
110 149
111static void do_write(int fd, void *buf, size_t size) 150static void do_write(int fd, void *buf, size_t size)
@@ -154,6 +193,11 @@ void perf_header__write(struct perf_header *self, int fd)
154 do_write(fd, &f_attr, sizeof(f_attr)); 193 do_write(fd, &f_attr, sizeof(f_attr));
155 } 194 }
156 195
196 self->event_offset = lseek(fd, 0, SEEK_CUR);
197 self->event_size = event_count * sizeof(struct perf_trace_event_type);
198 if (events)
199 do_write(fd, events, self->event_size);
200
157 201
158 self->data_offset = lseek(fd, 0, SEEK_CUR); 202 self->data_offset = lseek(fd, 0, SEEK_CUR);
159 203
@@ -169,6 +213,10 @@ void perf_header__write(struct perf_header *self, int fd)
169 .offset = self->data_offset, 213 .offset = self->data_offset,
170 .size = self->data_size, 214 .size = self->data_size,
171 }, 215 },
216 .event_types = {
217 .offset = self->event_offset,
218 .size = self->event_size,
219 },
172 }; 220 };
173 221
174 lseek(fd, 0, SEEK_SET); 222 lseek(fd, 0, SEEK_SET);
@@ -234,6 +282,17 @@ struct perf_header *perf_header__read(int fd)
234 lseek(fd, tmp, SEEK_SET); 282 lseek(fd, tmp, SEEK_SET);
235 } 283 }
236 284
285 if (f_header.event_types.size) {
286 lseek(fd, f_header.event_types.offset, SEEK_SET);
287 events = malloc(f_header.event_types.size);
288 if (!events)
289 die("nomem");
290 do_read(fd, events, f_header.event_types.size);
291 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
292 }
293 self->event_offset = f_header.event_types.offset;
294 self->event_size = f_header.event_types.size;
295
237 self->data_offset = f_header.data.offset; 296 self->data_offset = f_header.data.offset;
238 self->data_size = f_header.data.size; 297 self->data_size = f_header.data.size;
239 298
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 5d0a72ecc919..7b0e84a87179 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -19,6 +19,8 @@ struct perf_header {
19 s64 attr_offset; 19 s64 attr_offset;
20 u64 data_offset; 20 u64 data_offset;
21 u64 data_size; 21 u64 data_size;
22 u64 event_offset;
23 u64 event_size;
22}; 24};
23 25
24struct perf_header *perf_header__read(int fd); 26struct perf_header *perf_header__read(int fd);
@@ -27,6 +29,10 @@ void perf_header__write(struct perf_header *self, int fd);
27void perf_header__add_attr(struct perf_header *self, 29void perf_header__add_attr(struct perf_header *self,
28 struct perf_header_attr *attr); 30 struct perf_header_attr *attr);
29 31
32void perf_header__push_event(u64 id, const char *name);
33char *perf_header__find_event(u64 id);
34
35
30struct perf_header_attr * 36struct perf_header_attr *
31perf_header_attr__new(struct perf_counter_attr *attr); 37perf_header_attr__new(struct perf_counter_attr *attr);
32void perf_header_attr__add_id(struct perf_header_attr *self, u64 id); 38void perf_header_attr__add_id(struct perf_header_attr *self, u64 id);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index a9bdcab8c070..89172fd0038b 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -6,6 +6,7 @@
6#include "exec_cmd.h" 6#include "exec_cmd.h"
7#include "string.h" 7#include "string.h"
8#include "cache.h" 8#include "cache.h"
9#include "header.h"
9 10
10int nr_counters; 11int nr_counters;
11 12
@@ -687,11 +688,35 @@ modifier:
687 return ret; 688 return ret;
688} 689}
689 690
691static void store_event_type(const char *orgname)
692{
693 char filename[PATH_MAX], *c;
694 FILE *file;
695 int id;
696
697 sprintf(filename, "/sys/kernel/debug/tracing/events/%s/id", orgname);
698 c = strchr(filename, ':');
699 if (c)
700 *c = '/';
701
702 file = fopen(filename, "r");
703 if (!file)
704 return;
705 if (fscanf(file, "%i", &id) < 1)
706 die("cannot store event ID");
707 fclose(file);
708 perf_header__push_event(id, orgname);
709}
710
711
690int parse_events(const struct option *opt __used, const char *str, int unset __used) 712int parse_events(const struct option *opt __used, const char *str, int unset __used)
691{ 713{
692 struct perf_counter_attr attr; 714 struct perf_counter_attr attr;
693 enum event_result ret; 715 enum event_result ret;
694 716
717 if (strchr(str, ':'))
718 store_event_type(str);
719
695 for (;;) { 720 for (;;) {
696 if (nr_counters == MAX_COUNTERS) 721 if (nr_counters == MAX_COUNTERS)
697 return -1; 722 return -1;