aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/data_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/data_map.c')
-rw-r--r--tools/perf/util/data_map.c96
1 files changed, 53 insertions, 43 deletions
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index 6d46dda53a29..b557b836de3d 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -1,20 +1,17 @@
1#include "data_map.h"
2#include "symbol.h" 1#include "symbol.h"
3#include "util.h" 2#include "util.h"
4#include "debug.h" 3#include "debug.h"
4#include "thread.h"
5#include "session.h"
5 6
6 7static int process_event_stub(event_t *event __used,
7static struct perf_file_handler *curr_handler; 8 struct perf_session *session __used)
8static unsigned long mmap_window = 32;
9static char __cwd[PATH_MAX];
10
11static int process_event_stub(event_t *event __used)
12{ 9{
13 dump_printf(": unhandled!\n"); 10 dump_printf(": unhandled!\n");
14 return 0; 11 return 0;
15} 12}
16 13
17void register_perf_file_handler(struct perf_file_handler *handler) 14static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
18{ 15{
19 if (!handler->process_sample_event) 16 if (!handler->process_sample_event)
20 handler->process_sample_event = process_event_stub; 17 handler->process_sample_event = process_event_stub;
@@ -34,8 +31,6 @@ void register_perf_file_handler(struct perf_file_handler *handler)
34 handler->process_throttle_event = process_event_stub; 31 handler->process_throttle_event = process_event_stub;
35 if (!handler->process_unthrottle_event) 32 if (!handler->process_unthrottle_event)
36 handler->process_unthrottle_event = process_event_stub; 33 handler->process_unthrottle_event = process_event_stub;
37
38 curr_handler = handler;
39} 34}
40 35
41static const char *event__name[] = { 36static const char *event__name[] = {
@@ -61,8 +56,9 @@ void event__print_totals(void)
61 event__name[i], event__total[i]); 56 event__name[i], event__total[i]);
62} 57}
63 58
64static int 59static int process_event(event_t *event, struct perf_session *session,
65process_event(event_t *event, unsigned long offset, unsigned long head) 60 struct perf_event_ops *ops,
61 unsigned long offset, unsigned long head)
66{ 62{
67 trace_event(event); 63 trace_event(event);
68 64
@@ -77,25 +73,25 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
77 73
78 switch (event->header.type) { 74 switch (event->header.type) {
79 case PERF_RECORD_SAMPLE: 75 case PERF_RECORD_SAMPLE:
80 return curr_handler->process_sample_event(event); 76 return ops->process_sample_event(event, session);
81 case PERF_RECORD_MMAP: 77 case PERF_RECORD_MMAP:
82 return curr_handler->process_mmap_event(event); 78 return ops->process_mmap_event(event, session);
83 case PERF_RECORD_COMM: 79 case PERF_RECORD_COMM:
84 return curr_handler->process_comm_event(event); 80 return ops->process_comm_event(event, session);
85 case PERF_RECORD_FORK: 81 case PERF_RECORD_FORK:
86 return curr_handler->process_fork_event(event); 82 return ops->process_fork_event(event, session);
87 case PERF_RECORD_EXIT: 83 case PERF_RECORD_EXIT:
88 return curr_handler->process_exit_event(event); 84 return ops->process_exit_event(event, session);
89 case PERF_RECORD_LOST: 85 case PERF_RECORD_LOST:
90 return curr_handler->process_lost_event(event); 86 return ops->process_lost_event(event, session);
91 case PERF_RECORD_READ: 87 case PERF_RECORD_READ:
92 return curr_handler->process_read_event(event); 88 return ops->process_read_event(event, session);
93 case PERF_RECORD_THROTTLE: 89 case PERF_RECORD_THROTTLE:
94 return curr_handler->process_throttle_event(event); 90 return ops->process_throttle_event(event, session);
95 case PERF_RECORD_UNTHROTTLE: 91 case PERF_RECORD_UNTHROTTLE:
96 return curr_handler->process_unthrottle_event(event); 92 return ops->process_unthrottle_event(event, session);
97 default: 93 default:
98 curr_handler->total_unknown++; 94 ops->total_unknown++;
99 return -1; 95 return -1;
100 } 96 }
101} 97}
@@ -129,44 +125,58 @@ out:
129 return err; 125 return err;
130} 126}
131 127
128static struct thread *perf_session__register_idle_thread(struct perf_session *self)
129{
130 struct thread *thread = perf_session__findnew(self, 0);
131
132 if (!thread || thread__set_comm(thread, "swapper")) {
133 pr_err("problem inserting idle task.\n");
134 thread = NULL;
135 }
136
137 return thread;
138}
139
132int perf_session__process_events(struct perf_session *self, 140int perf_session__process_events(struct perf_session *self,
133 int full_paths, int *cwdlen, char **cwd) 141 struct perf_event_ops *ops)
134{ 142{
135 int err; 143 int err;
136 unsigned long head, shift; 144 unsigned long head, shift;
137 unsigned long offset = 0; 145 unsigned long offset = 0;
138 size_t page_size; 146 size_t page_size;
139 u64 sample_type;
140 event_t *event; 147 event_t *event;
141 uint32_t size; 148 uint32_t size;
142 char *buf; 149 char *buf;
143 150
144 if (curr_handler == NULL) { 151 if (perf_session__register_idle_thread(self) == NULL)
145 pr_debug("Forgot to register perf file handler\n"); 152 return -ENOMEM;
146 return -EINVAL; 153
147 } 154 perf_event_ops__fill_defaults(ops);
148 155
149 page_size = getpagesize(); 156 page_size = getpagesize();
150 157
151 head = self->header.data_offset; 158 head = self->header.data_offset;
152 sample_type = perf_header__sample_type(&self->header); 159 self->sample_type = perf_header__sample_type(&self->header);
153 160
154 err = -EINVAL; 161 err = -EINVAL;
155 if (curr_handler->sample_type_check && 162 if (ops->sample_type_check && ops->sample_type_check(self) < 0)
156 curr_handler->sample_type_check(sample_type) < 0)
157 goto out_err; 163 goto out_err;
158 164
159 if (!full_paths) { 165 if (!ops->full_paths) {
160 if (getcwd(__cwd, sizeof(__cwd)) == NULL) { 166 char bf[PATH_MAX];
161 pr_err("failed to get the current directory\n"); 167
168 if (getcwd(bf, sizeof(bf)) == NULL) {
162 err = -errno; 169 err = -errno;
170out_getcwd_err:
171 pr_err("failed to get the current directory\n");
163 goto out_err; 172 goto out_err;
164 } 173 }
165 *cwd = __cwd; 174 self->cwd = strdup(bf);
166 *cwdlen = strlen(*cwd); 175 if (self->cwd == NULL) {
167 } else { 176 err = -ENOMEM;
168 *cwd = NULL; 177 goto out_getcwd_err;
169 *cwdlen = 0; 178 }
179 self->cwdlen = strlen(self->cwd);
170 } 180 }
171 181
172 shift = page_size * (head / page_size); 182 shift = page_size * (head / page_size);
@@ -174,7 +184,7 @@ int perf_session__process_events(struct perf_session *self,
174 head -= shift; 184 head -= shift;
175 185
176remap: 186remap:
177 buf = mmap(NULL, page_size * mmap_window, PROT_READ, 187 buf = mmap(NULL, page_size * self->mmap_window, PROT_READ,
178 MAP_SHARED, self->fd, offset); 188 MAP_SHARED, self->fd, offset);
179 if (buf == MAP_FAILED) { 189 if (buf == MAP_FAILED) {
180 pr_err("failed to mmap file\n"); 190 pr_err("failed to mmap file\n");
@@ -189,12 +199,12 @@ more:
189 if (!size) 199 if (!size)
190 size = 8; 200 size = 8;
191 201
192 if (head + event->header.size >= page_size * mmap_window) { 202 if (head + event->header.size >= page_size * self->mmap_window) {
193 int munmap_ret; 203 int munmap_ret;
194 204
195 shift = page_size * (head / page_size); 205 shift = page_size * (head / page_size);
196 206
197 munmap_ret = munmap(buf, page_size * mmap_window); 207 munmap_ret = munmap(buf, page_size * self->mmap_window);
198 assert(munmap_ret == 0); 208 assert(munmap_ret == 0);
199 209
200 offset += shift; 210 offset += shift;
@@ -209,7 +219,7 @@ more:
209 (void *)(long)event->header.size, 219 (void *)(long)event->header.size,
210 event->header.type); 220 event->header.type);
211 221
212 if (!size || process_event(event, offset, head) < 0) { 222 if (!size || process_event(event, self, ops, offset, head) < 0) {
213 223
214 dump_printf("%p [%p]: skipping unknown header type: %d\n", 224 dump_printf("%p [%p]: skipping unknown header type: %d\n",
215 (void *)(offset + head), 225 (void *)(offset + head),