aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-record.c7
-rw-r--r--tools/perf/builtin-report.c1
-rw-r--r--tools/perf/builtin-trace.c1
-rw-r--r--tools/perf/util/event.h14
-rw-r--r--tools/perf/util/header.c62
-rw-r--r--tools/perf/util/header.h9
-rw-r--r--tools/perf/util/session.c12
-rw-r--r--tools/perf/util/session.h3
8 files changed, 101 insertions, 8 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 289d9cf3bf7..c4c132205ed 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -592,6 +592,13 @@ static int __cmd_record(int argc, const char **argv)
592 pr_err("Couldn't synthesize attrs.\n"); 592 pr_err("Couldn't synthesize attrs.\n");
593 return err; 593 return err;
594 } 594 }
595
596 err = event__synthesize_event_types(process_synthesized_event,
597 session);
598 if (err < 0) {
599 pr_err("Couldn't synthesize event_types.\n");
600 return err;
601 }
595 } 602 }
596 603
597 err = event__synthesize_kernel_mmap(process_synthesized_event, 604 err = event__synthesize_kernel_mmap(process_synthesized_event,
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index f0486ce591a..e59d0127d5e 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -268,6 +268,7 @@ static struct perf_event_ops event_ops = {
268 .lost = event__process_lost, 268 .lost = event__process_lost,
269 .read = process_read_event, 269 .read = process_read_event,
270 .attr = event__process_attr, 270 .attr = event__process_attr,
271 .event_type = event__process_event_type,
271}; 272};
272 273
273extern volatile int session_done; 274extern volatile int session_done;
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index e30eac6af54..eb884a7dc24 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -105,6 +105,7 @@ static struct perf_event_ops event_ops = {
105 .sample = process_sample_event, 105 .sample = process_sample_event,
106 .comm = event__process_comm, 106 .comm = event__process_comm,
107 .attr = event__process_attr, 107 .attr = event__process_attr,
108 .event_type = event__process_event_type,
108}; 109};
109 110
110extern volatile int session_done; 111extern volatile int session_done;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index b4fbf25078b..c720fe06f8d 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -85,6 +85,7 @@ struct build_id_event {
85 85
86enum perf_header_event_type { /* above any possible kernel type */ 86enum 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_MAX 89 PERF_RECORD_HEADER_MAX
89}; 90};
90 91
@@ -94,6 +95,18 @@ struct attr_event {
94 u64 id[]; 95 u64 id[];
95}; 96};
96 97
98#define MAX_EVENT_NAME 64
99
100struct perf_trace_event_type {
101 u64 event_id;
102 char name[MAX_EVENT_NAME];
103};
104
105struct event_type_event {
106 struct perf_event_header header;
107 struct perf_trace_event_type event_type;
108};
109
97typedef union event_union { 110typedef union event_union {
98 struct perf_event_header header; 111 struct perf_event_header header;
99 struct ip_event ip; 112 struct ip_event ip;
@@ -104,6 +117,7 @@ typedef union event_union {
104 struct read_event read; 117 struct read_event read;
105 struct sample_event sample; 118 struct sample_event sample;
106 struct attr_event attr; 119 struct attr_event attr;
120 struct event_type_event event_type;
107} event_t; 121} event_t;
108 122
109struct events_stats { 123struct events_stats {
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index e36173934e8..44637999dbc 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -99,13 +99,6 @@ int perf_header__add_attr(struct perf_header *self,
99 return 0; 99 return 0;
100} 100}
101 101
102#define MAX_EVENT_NAME 64
103
104struct perf_trace_event_type {
105 u64 event_id;
106 char name[MAX_EVENT_NAME];
107};
108
109static int event_count; 102static int event_count;
110static struct perf_trace_event_type *events; 103static struct perf_trace_event_type *events;
111 104
@@ -886,3 +879,58 @@ int event__process_attr(event_t *self, struct perf_session *session)
886 879
887 return 0; 880 return 0;
888} 881}
882
883int event__synthesize_event_type(u64 event_id, char *name,
884 event__handler_t process,
885 struct perf_session *session)
886{
887 event_t ev;
888 size_t size = 0;
889 int err = 0;
890
891 memset(&ev, 0, sizeof(ev));
892
893 ev.event_type.event_type.event_id = event_id;
894 memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME);
895 strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1);
896
897 ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE;
898 size = strlen(name);
899 size = ALIGN(size, sizeof(u64));
900 ev.event_type.header.size = sizeof(ev.event_type) -
901 (sizeof(ev.event_type.event_type.name) - size);
902
903 err = process(&ev, session);
904
905 return err;
906}
907
908int event__synthesize_event_types(event__handler_t process,
909 struct perf_session *session)
910{
911 struct perf_trace_event_type *type;
912 int i, err = 0;
913
914 for (i = 0; i < event_count; i++) {
915 type = &events[i];
916
917 err = event__synthesize_event_type(type->event_id, type->name,
918 process, session);
919 if (err) {
920 pr_debug("failed to create perf header event type\n");
921 return err;
922 }
923 }
924
925 return err;
926}
927
928int event__process_event_type(event_t *self,
929 struct perf_session *session __unused)
930{
931 if (perf_header__push_event(self->event_type.event_type.event_id,
932 self->event_type.event_type.name) < 0)
933 return -ENOMEM;
934
935 return 0;
936}
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index e916ac509a6..afeb6188376 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -103,4 +103,13 @@ int event__synthesize_attrs(struct perf_header *self,
103 struct perf_session *session); 103 struct perf_session *session);
104int event__process_attr(event_t *self, struct perf_session *session); 104int event__process_attr(event_t *self, struct perf_session *session);
105 105
106int event__synthesize_event_type(u64 event_id, char *name,
107 event__handler_t process,
108 struct perf_session *session);
109int event__synthesize_event_types(event__handler_t process,
110 struct perf_session *session);
111int event__process_event_type(event_t *self,
112 struct perf_session *session);
113
114
106#endif /* __PERF_HEADER_H */ 115#endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index bc81864cd04..96c4629b774 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -202,6 +202,8 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
202 handler->unthrottle = process_event_stub; 202 handler->unthrottle = process_event_stub;
203 if (handler->attr == NULL) 203 if (handler->attr == NULL)
204 handler->attr = process_event_stub; 204 handler->attr = process_event_stub;
205 if (handler->event_type == NULL)
206 handler->event_type = process_event_stub;
205} 207}
206 208
207static const char *event__name[] = { 209static const char *event__name[] = {
@@ -216,6 +218,7 @@ static const char *event__name[] = {
216 [PERF_RECORD_READ] = "READ", 218 [PERF_RECORD_READ] = "READ",
217 [PERF_RECORD_SAMPLE] = "SAMPLE", 219 [PERF_RECORD_SAMPLE] = "SAMPLE",
218 [PERF_RECORD_HEADER_ATTR] = "ATTR", 220 [PERF_RECORD_HEADER_ATTR] = "ATTR",
221 [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE",
219}; 222};
220 223
221unsigned long event__total[PERF_RECORD_HEADER_MAX]; 224unsigned long event__total[PERF_RECORD_HEADER_MAX];
@@ -302,6 +305,12 @@ static void event__attr_swap(event_t *self)
302 mem_bswap_64(self->attr.id, size); 305 mem_bswap_64(self->attr.id, size);
303} 306}
304 307
308static void event__event_type_swap(event_t *self)
309{
310 self->event_type.event_type.event_id =
311 bswap_64(self->event_type.event_type.event_id);
312}
313
305typedef void (*event__swap_op)(event_t *self); 314typedef void (*event__swap_op)(event_t *self);
306 315
307static event__swap_op event__swap_ops[] = { 316static event__swap_op event__swap_ops[] = {
@@ -313,6 +322,7 @@ static event__swap_op event__swap_ops[] = {
313 [PERF_RECORD_READ] = event__read_swap, 322 [PERF_RECORD_READ] = event__read_swap,
314 [PERF_RECORD_SAMPLE] = event__all64_swap, 323 [PERF_RECORD_SAMPLE] = event__all64_swap,
315 [PERF_RECORD_HEADER_ATTR] = event__attr_swap, 324 [PERF_RECORD_HEADER_ATTR] = event__attr_swap,
325 [PERF_RECORD_HEADER_EVENT_TYPE] = event__event_type_swap,
316 [PERF_RECORD_HEADER_MAX] = NULL, 326 [PERF_RECORD_HEADER_MAX] = NULL,
317}; 327};
318 328
@@ -355,6 +365,8 @@ static int perf_session__process_event(struct perf_session *self,
355 return ops->unthrottle(event, self); 365 return ops->unthrottle(event, self);
356 case PERF_RECORD_HEADER_ATTR: 366 case PERF_RECORD_HEADER_ATTR:
357 return ops->attr(event, self); 367 return ops->attr(event, self);
368 case PERF_RECORD_HEADER_EVENT_TYPE:
369 return ops->event_type(event, self);
358 default: 370 default:
359 self->unknown_events++; 371 self->unknown_events++;
360 return -1; 372 return -1;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 45a13741351..0dac1f4457d 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -45,7 +45,8 @@ struct perf_event_ops {
45 read, 45 read,
46 throttle, 46 throttle,
47 unthrottle, 47 unthrottle,
48 attr; 48 attr,
49 event_type;
49}; 50};
50 51
51struct perf_session *perf_session__new(const char *filename, int mode, bool force); 52struct perf_session *perf_session__new(const char *filename, int mode, bool force);