aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c108
1 files changed, 98 insertions, 10 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index e3ccdb46d6c4..604e14f6a6f9 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1,5 +1,6 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2 2
3#include <byteswap.h>
3#include <unistd.h> 4#include <unistd.h>
4#include <sys/types.h> 5#include <sys/types.h>
5 6
@@ -201,21 +202,88 @@ void event__print_totals(void)
201 event__name[i], event__total[i]); 202 event__name[i], event__total[i]);
202} 203}
203 204
205void mem_bswap_64(void *src, int byte_size)
206{
207 u64 *m = src;
208
209 while (byte_size > 0) {
210 *m = bswap_64(*m);
211 byte_size -= sizeof(u64);
212 ++m;
213 }
214}
215
216static void event__all64_swap(event_t *self)
217{
218 struct perf_event_header *hdr = &self->header;
219 mem_bswap_64(hdr + 1, self->header.size - sizeof(*hdr));
220}
221
222static void event__comm_swap(event_t *self)
223{
224 self->comm.pid = bswap_32(self->comm.pid);
225 self->comm.tid = bswap_32(self->comm.tid);
226}
227
228static void event__mmap_swap(event_t *self)
229{
230 self->mmap.pid = bswap_32(self->mmap.pid);
231 self->mmap.tid = bswap_32(self->mmap.tid);
232 self->mmap.start = bswap_64(self->mmap.start);
233 self->mmap.len = bswap_64(self->mmap.len);
234 self->mmap.pgoff = bswap_64(self->mmap.pgoff);
235}
236
237static void event__task_swap(event_t *self)
238{
239 self->fork.pid = bswap_32(self->fork.pid);
240 self->fork.tid = bswap_32(self->fork.tid);
241 self->fork.ppid = bswap_32(self->fork.ppid);
242 self->fork.ptid = bswap_32(self->fork.ptid);
243 self->fork.time = bswap_64(self->fork.time);
244}
245
246static void event__read_swap(event_t *self)
247{
248 self->read.pid = bswap_32(self->read.pid);
249 self->read.tid = bswap_32(self->read.tid);
250 self->read.value = bswap_64(self->read.value);
251 self->read.time_enabled = bswap_64(self->read.time_enabled);
252 self->read.time_running = bswap_64(self->read.time_running);
253 self->read.id = bswap_64(self->read.id);
254}
255
256typedef void (*event__swap_op)(event_t *self);
257
258static event__swap_op event__swap_ops[] = {
259 [PERF_RECORD_MMAP] = event__mmap_swap,
260 [PERF_RECORD_COMM] = event__comm_swap,
261 [PERF_RECORD_FORK] = event__task_swap,
262 [PERF_RECORD_EXIT] = event__task_swap,
263 [PERF_RECORD_LOST] = event__all64_swap,
264 [PERF_RECORD_READ] = event__read_swap,
265 [PERF_RECORD_SAMPLE] = event__all64_swap,
266 [PERF_RECORD_MAX] = NULL,
267};
268
204static int perf_session__process_event(struct perf_session *self, 269static int perf_session__process_event(struct perf_session *self,
205 event_t *event, 270 event_t *event,
206 struct perf_event_ops *ops, 271 struct perf_event_ops *ops,
207 unsigned long offset, unsigned long head) 272 u64 offset, u64 head)
208{ 273{
209 trace_event(event); 274 trace_event(event);
210 275
211 if (event->header.type < PERF_RECORD_MAX) { 276 if (event->header.type < PERF_RECORD_MAX) {
212 dump_printf("%#lx [%#x]: PERF_RECORD_%s", 277 dump_printf("%#Lx [%#x]: PERF_RECORD_%s",
213 offset + head, event->header.size, 278 offset + head, event->header.size,
214 event__name[event->header.type]); 279 event__name[event->header.type]);
215 ++event__total[0]; 280 ++event__total[0];
216 ++event__total[event->header.type]; 281 ++event__total[event->header.type];
217 } 282 }
218 283
284 if (self->header.needs_swap && event__swap_ops[event->header.type])
285 event__swap_ops[event->header.type](event);
286
219 switch (event->header.type) { 287 switch (event->header.type) {
220 case PERF_RECORD_SAMPLE: 288 case PERF_RECORD_SAMPLE:
221 return ops->sample(event, self); 289 return ops->sample(event, self);
@@ -241,7 +309,15 @@ static int perf_session__process_event(struct perf_session *self,
241 } 309 }
242} 310}
243 311
244int perf_header__read_build_ids(int input, u64 offset, u64 size) 312void perf_event_header__bswap(struct perf_event_header *self)
313{
314 self->type = bswap_32(self->type);
315 self->misc = bswap_16(self->misc);
316 self->size = bswap_16(self->size);
317}
318
319int perf_header__read_build_ids(struct perf_header *self,
320 int input, u64 offset, u64 size)
245{ 321{
246 struct build_id_event bev; 322 struct build_id_event bev;
247 char filename[PATH_MAX]; 323 char filename[PATH_MAX];
@@ -256,6 +332,9 @@ int perf_header__read_build_ids(int input, u64 offset, u64 size)
256 if (read(input, &bev, sizeof(bev)) != sizeof(bev)) 332 if (read(input, &bev, sizeof(bev)) != sizeof(bev))
257 goto out; 333 goto out;
258 334
335 if (self->needs_swap)
336 perf_event_header__bswap(&bev.header);
337
259 len = bev.header.size - sizeof(bev); 338 len = bev.header.size - sizeof(bev);
260 if (read(input, filename, len) != len) 339 if (read(input, filename, len) != len)
261 goto out; 340 goto out;
@@ -292,9 +371,9 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se
292int perf_session__process_events(struct perf_session *self, 371int perf_session__process_events(struct perf_session *self,
293 struct perf_event_ops *ops) 372 struct perf_event_ops *ops)
294{ 373{
295 int err; 374 int err, mmap_prot, mmap_flags;
296 unsigned long head, shift; 375 u64 head, shift;
297 unsigned long offset = 0; 376 u64 offset = 0;
298 size_t page_size; 377 size_t page_size;
299 event_t *event; 378 event_t *event;
300 uint32_t size; 379 uint32_t size;
@@ -330,9 +409,16 @@ out_getcwd_err:
330 offset += shift; 409 offset += shift;
331 head -= shift; 410 head -= shift;
332 411
412 mmap_prot = PROT_READ;
413 mmap_flags = MAP_SHARED;
414
415 if (self->header.needs_swap) {
416 mmap_prot |= PROT_WRITE;
417 mmap_flags = MAP_PRIVATE;
418 }
333remap: 419remap:
334 buf = mmap(NULL, page_size * self->mmap_window, PROT_READ, 420 buf = mmap(NULL, page_size * self->mmap_window, mmap_prot,
335 MAP_SHARED, self->fd, offset); 421 mmap_flags, self->fd, offset);
336 if (buf == MAP_FAILED) { 422 if (buf == MAP_FAILED) {
337 pr_err("failed to mmap file\n"); 423 pr_err("failed to mmap file\n");
338 err = -errno; 424 err = -errno;
@@ -342,6 +428,8 @@ remap:
342more: 428more:
343 event = (event_t *)(buf + head); 429 event = (event_t *)(buf + head);
344 430
431 if (self->header.needs_swap)
432 perf_event_header__bswap(&event->header);
345 size = event->header.size; 433 size = event->header.size;
346 if (size == 0) 434 if (size == 0)
347 size = 8; 435 size = 8;
@@ -361,12 +449,12 @@ more:
361 449
362 size = event->header.size; 450 size = event->header.size;
363 451
364 dump_printf("\n%#lx [%#x]: event: %d\n", 452 dump_printf("\n%#Lx [%#x]: event: %d\n",
365 offset + head, event->header.size, event->header.type); 453 offset + head, event->header.size, event->header.type);
366 454
367 if (size == 0 || 455 if (size == 0 ||
368 perf_session__process_event(self, event, ops, offset, head) < 0) { 456 perf_session__process_event(self, event, ops, offset, head) < 0) {
369 dump_printf("%#lx [%#x]: skipping unknown header type: %d\n", 457 dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n",
370 offset + head, event->header.size, 458 offset + head, event->header.size,
371 event->header.type); 459 event->header.type);
372 /* 460 /*