diff options
author | Tom Zanussi <tzanussi@gmail.com> | 2010-04-02 00:59:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-04-14 05:56:08 -0400 |
commit | c7929e4727e8ff2d6fc8327188820e3b1c2f1dc3 (patch) | |
tree | 59f85cc7a5a381761f1583624f1ce2d62c060e5d /tools/perf/util | |
parent | 9215545e99d8c0b27323df2de504f4294bf5e407 (diff) |
perf: Convert perf header build_ids into build_id events
Bypasses the build_id perf header code and replaces it with a
synthesized event and processing function that accomplishes the
same thing, used when reading/writing perf data to/from a pipe.
Signed-off-by: Tom Zanussi <tzanussi@gmail.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: fweisbec@gmail.com
Cc: rostedt@goodmis.org
Cc: k-keiichi@bx.jp.nec.com
Cc: acme@ghostprotocols.net
LKML-Reference: <1270184365-8281-9-git-send-email-tzanussi@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/event.h | 2 | ||||
-rw-r--r-- | tools/perf/util/header.c | 90 | ||||
-rw-r--r-- | tools/perf/util/header.h | 7 | ||||
-rw-r--r-- | tools/perf/util/session.c | 6 | ||||
-rw-r--r-- | tools/perf/util/session.h | 3 |
5 files changed, 107 insertions, 1 deletions
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index b896a177ea4..e5740ea140a 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -87,6 +87,7 @@ enum perf_header_event_type { /* above any possible kernel type */ | |||
87 | PERF_RECORD_HEADER_ATTR = 64, | 87 | PERF_RECORD_HEADER_ATTR = 64, |
88 | PERF_RECORD_HEADER_EVENT_TYPE = 65, | 88 | PERF_RECORD_HEADER_EVENT_TYPE = 65, |
89 | PERF_RECORD_HEADER_TRACING_DATA = 66, | 89 | PERF_RECORD_HEADER_TRACING_DATA = 66, |
90 | PERF_RECORD_HEADER_BUILD_ID = 67, | ||
90 | PERF_RECORD_HEADER_MAX | 91 | PERF_RECORD_HEADER_MAX |
91 | }; | 92 | }; |
92 | 93 | ||
@@ -125,6 +126,7 @@ typedef union event_union { | |||
125 | struct attr_event attr; | 126 | struct attr_event attr; |
126 | struct event_type_event event_type; | 127 | struct event_type_event event_type; |
127 | struct tracing_data_event tracing_data; | 128 | struct tracing_data_event tracing_data; |
129 | struct build_id_event build_id; | ||
128 | } event_t; | 130 | } event_t; |
129 | 131 | ||
130 | struct events_stats { | 132 | struct events_stats { |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index c6874ecc90b..628173ba689 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -986,3 +986,93 @@ int event__process_tracing_data(event_t *self, | |||
986 | 986 | ||
987 | return size_read + padding; | 987 | return size_read + padding; |
988 | } | 988 | } |
989 | |||
990 | int event__synthesize_build_id(struct dso *pos, u16 misc, | ||
991 | event__handler_t process, | ||
992 | struct perf_session *session) | ||
993 | { | ||
994 | event_t ev; | ||
995 | size_t len; | ||
996 | int err = 0; | ||
997 | |||
998 | if (!pos->hit) | ||
999 | return err; | ||
1000 | |||
1001 | memset(&ev, 0, sizeof(ev)); | ||
1002 | |||
1003 | len = pos->long_name_len + 1; | ||
1004 | len = ALIGN(len, NAME_ALIGN); | ||
1005 | memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id)); | ||
1006 | ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; | ||
1007 | ev.build_id.header.misc = misc; | ||
1008 | ev.build_id.header.size = sizeof(ev.build_id) + len; | ||
1009 | memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); | ||
1010 | |||
1011 | err = process(&ev, session); | ||
1012 | |||
1013 | return err; | ||
1014 | } | ||
1015 | |||
1016 | static int __event_synthesize_build_ids(struct list_head *head, u16 misc, | ||
1017 | event__handler_t process, | ||
1018 | struct perf_session *session) | ||
1019 | { | ||
1020 | struct dso *pos; | ||
1021 | |||
1022 | dsos__for_each_with_build_id(pos, head) { | ||
1023 | int err; | ||
1024 | if (!pos->hit) | ||
1025 | continue; | ||
1026 | |||
1027 | err = event__synthesize_build_id(pos, misc, process, session); | ||
1028 | if (err < 0) | ||
1029 | return err; | ||
1030 | } | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | int event__synthesize_build_ids(event__handler_t process, | ||
1036 | struct perf_session *session) | ||
1037 | { | ||
1038 | int err; | ||
1039 | |||
1040 | if (!dsos__read_build_ids(true)) | ||
1041 | return 0; | ||
1042 | |||
1043 | err = __event_synthesize_build_ids(&dsos__kernel, | ||
1044 | PERF_RECORD_MISC_KERNEL, | ||
1045 | process, session); | ||
1046 | if (err == 0) | ||
1047 | err = __event_synthesize_build_ids(&dsos__user, | ||
1048 | PERF_RECORD_MISC_USER, | ||
1049 | process, session); | ||
1050 | |||
1051 | if (err < 0) { | ||
1052 | pr_debug("failed to synthesize build ids\n"); | ||
1053 | return err; | ||
1054 | } | ||
1055 | |||
1056 | dsos__cache_build_ids(); | ||
1057 | |||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1061 | int event__process_build_id(event_t *self, | ||
1062 | struct perf_session *session __unused) | ||
1063 | { | ||
1064 | struct list_head *head = &dsos__user; | ||
1065 | struct dso *dso; | ||
1066 | |||
1067 | if (self->build_id.header.misc & PERF_RECORD_MISC_KERNEL) | ||
1068 | head = &dsos__kernel; | ||
1069 | |||
1070 | dso = __dsos__findnew(head, self->build_id.filename); | ||
1071 | if (dso != NULL) { | ||
1072 | dso__set_build_id(dso, &self->build_id.build_id); | ||
1073 | if (head == &dsos__kernel && self->build_id.filename[0] == '[') | ||
1074 | dso->kernel = 1; | ||
1075 | } | ||
1076 | |||
1077 | return 0; | ||
1078 | } | ||
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 3ed3d98c81d..4214e237565 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h | |||
@@ -118,4 +118,11 @@ int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs, | |||
118 | int event__process_tracing_data(event_t *self, | 118 | int event__process_tracing_data(event_t *self, |
119 | struct perf_session *session); | 119 | struct perf_session *session); |
120 | 120 | ||
121 | int event__synthesize_build_id(struct dso *pos, u16 misc, | ||
122 | event__handler_t process, | ||
123 | struct perf_session *session); | ||
124 | int event__synthesize_build_ids(event__handler_t process, | ||
125 | struct perf_session *session); | ||
126 | int event__process_build_id(event_t *self, struct perf_session *session); | ||
127 | |||
121 | #endif /* __PERF_HEADER_H */ | 128 | #endif /* __PERF_HEADER_H */ |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 1516c40d47a..0fdf3ebef1e 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -206,6 +206,8 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) | |||
206 | handler->event_type = process_event_stub; | 206 | handler->event_type = process_event_stub; |
207 | if (handler->tracing_data == NULL) | 207 | if (handler->tracing_data == NULL) |
208 | handler->tracing_data = process_event_stub; | 208 | handler->tracing_data = process_event_stub; |
209 | if (handler->build_id == NULL) | ||
210 | handler->build_id = process_event_stub; | ||
209 | } | 211 | } |
210 | 212 | ||
211 | static const char *event__name[] = { | 213 | static const char *event__name[] = { |
@@ -222,6 +224,7 @@ static const char *event__name[] = { | |||
222 | [PERF_RECORD_HEADER_ATTR] = "ATTR", | 224 | [PERF_RECORD_HEADER_ATTR] = "ATTR", |
223 | [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", | 225 | [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", |
224 | [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", | 226 | [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", |
227 | [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", | ||
225 | }; | 228 | }; |
226 | 229 | ||
227 | unsigned long event__total[PERF_RECORD_HEADER_MAX]; | 230 | unsigned long event__total[PERF_RECORD_HEADER_MAX]; |
@@ -332,6 +335,7 @@ static event__swap_op event__swap_ops[] = { | |||
332 | [PERF_RECORD_HEADER_ATTR] = event__attr_swap, | 335 | [PERF_RECORD_HEADER_ATTR] = event__attr_swap, |
333 | [PERF_RECORD_HEADER_EVENT_TYPE] = event__event_type_swap, | 336 | [PERF_RECORD_HEADER_EVENT_TYPE] = event__event_type_swap, |
334 | [PERF_RECORD_HEADER_TRACING_DATA] = event__tracing_data_swap, | 337 | [PERF_RECORD_HEADER_TRACING_DATA] = event__tracing_data_swap, |
338 | [PERF_RECORD_HEADER_BUILD_ID] = NULL, | ||
335 | [PERF_RECORD_HEADER_MAX] = NULL, | 339 | [PERF_RECORD_HEADER_MAX] = NULL, |
336 | }; | 340 | }; |
337 | 341 | ||
@@ -380,6 +384,8 @@ static int perf_session__process_event(struct perf_session *self, | |||
380 | /* setup for reading amidst mmap */ | 384 | /* setup for reading amidst mmap */ |
381 | lseek(self->fd, offset + head, SEEK_SET); | 385 | lseek(self->fd, offset + head, SEEK_SET); |
382 | return ops->tracing_data(event, self); | 386 | return ops->tracing_data(event, self); |
387 | case PERF_RECORD_HEADER_BUILD_ID: | ||
388 | return ops->build_id(event, self); | ||
383 | default: | 389 | default: |
384 | self->unknown_events++; | 390 | self->unknown_events++; |
385 | return -1; | 391 | return -1; |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 0739ebbbf9f..0ac14d42dc2 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -47,7 +47,8 @@ struct perf_event_ops { | |||
47 | unthrottle, | 47 | unthrottle, |
48 | attr, | 48 | attr, |
49 | event_type, | 49 | event_type, |
50 | tracing_data; | 50 | tracing_data, |
51 | build_id; | ||
51 | }; | 52 | }; |
52 | 53 | ||
53 | struct perf_session *perf_session__new(const char *filename, int mode, bool force); | 54 | struct perf_session *perf_session__new(const char *filename, int mode, bool force); |