aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2010-04-02 00:59:22 -0400
committerIngo Molnar <mingo@elte.hu>2010-04-14 05:56:08 -0400
commitc7929e4727e8ff2d6fc8327188820e3b1c2f1dc3 (patch)
tree59f85cc7a5a381761f1583624f1ce2d62c060e5d
parent9215545e99d8c0b27323df2de504f4294bf5e407 (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.c15
-rw-r--r--tools/perf/builtin-report.c1
-rw-r--r--tools/perf/builtin-trace.c1
-rw-r--r--tools/perf/util/event.h2
-rw-r--r--tools/perf/util/header.c90
-rw-r--r--tools/perf/util/header.h7
-rw-r--r--tools/perf/util/session.c6
-rw-r--r--tools/perf/util/session.h3
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
427static void atexit_header(void) 427static 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
435static int __cmd_record(int argc, const char **argv) 444static 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
275extern volatile int session_done; 276extern 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
112extern volatile int session_done; 113extern 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
130struct events_stats { 132struct 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
990int 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
1016static 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
1035int 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
1061int 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,
118int event__process_tracing_data(event_t *self, 118int event__process_tracing_data(event_t *self,
119 struct perf_session *session); 119 struct perf_session *session);
120 120
121int event__synthesize_build_id(struct dso *pos, u16 misc,
122 event__handler_t process,
123 struct perf_session *session);
124int event__synthesize_build_ids(event__handler_t process,
125 struct perf_session *session);
126int 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
211static const char *event__name[] = { 213static 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
227unsigned long event__total[PERF_RECORD_HEADER_MAX]; 230unsigned 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
53struct perf_session *perf_session__new(const char *filename, int mode, bool force); 54struct perf_session *perf_session__new(const char *filename, int mode, bool force);