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 | |
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>
-rw-r--r-- | tools/perf/builtin-record.c | 15 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 1 | ||||
-rw-r--r-- | tools/perf/builtin-trace.c | 1 | ||||
-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 |
8 files changed, 121 insertions, 4 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 3775abe2af78..0bde31bc8e2e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -426,10 +426,19 @@ static int process_buildids(void) | |||
426 | 426 | ||
427 | static void atexit_header(void) | 427 | static void atexit_header(void) |
428 | { | 428 | { |
429 | session->header.data_size += bytes_written; | 429 | if (!pipe_output) { |
430 | session->header.data_size += bytes_written; | ||
430 | 431 | ||
431 | process_buildids(); | 432 | process_buildids(); |
432 | perf_header__write(&session->header, output, true); | 433 | perf_header__write(&session->header, output, true); |
434 | } else { | ||
435 | int err; | ||
436 | |||
437 | err = event__synthesize_build_ids(process_synthesized_event, | ||
438 | session); | ||
439 | if (err < 0) | ||
440 | pr_err("Couldn't synthesize build ids.\n"); | ||
441 | } | ||
433 | } | 442 | } |
434 | 443 | ||
435 | static int __cmd_record(int argc, const char **argv) | 444 | static int __cmd_record(int argc, const char **argv) |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 76f03a70aaca..7da5fb365264 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -270,6 +270,7 @@ static struct perf_event_ops event_ops = { | |||
270 | .attr = event__process_attr, | 270 | .attr = event__process_attr, |
271 | .event_type = event__process_event_type, | 271 | .event_type = event__process_event_type, |
272 | .tracing_data = event__process_tracing_data, | 272 | .tracing_data = event__process_tracing_data, |
273 | .build_id = event__process_build_id, | ||
273 | }; | 274 | }; |
274 | 275 | ||
275 | extern volatile int session_done; | 276 | extern volatile int session_done; |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 1509744429c8..1ee1e3006649 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -107,6 +107,7 @@ static struct perf_event_ops event_ops = { | |||
107 | .attr = event__process_attr, | 107 | .attr = event__process_attr, |
108 | .event_type = event__process_event_type, | 108 | .event_type = event__process_event_type, |
109 | .tracing_data = event__process_tracing_data, | 109 | .tracing_data = event__process_tracing_data, |
110 | .build_id = event__process_build_id, | ||
110 | }; | 111 | }; |
111 | 112 | ||
112 | extern volatile int session_done; | 113 | extern volatile int session_done; |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index b896a177ea41..e5740ea140ab 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 c6874ecc90b8..628173ba689e 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 3ed3d98c81d4..4214e2375650 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 1516c40d47ac..0fdf3ebef1e9 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 0739ebbbf9fd..0ac14d42dc28 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); |