aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2010-11-30 12:49:49 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-11-30 17:01:08 -0500
commitfe17420784a6d3602e98f798731369fa05936cbe (patch)
tree7c55a62a093b6c640114c07dd18f634a17073b97 /tools/perf/util/session.c
parent55b44629f599a2305265ae9c77f9d9bcfd6ddc17 (diff)
perf session: Keep file mmaped instead of malloc/memcpy
Profiling perf with perf revealed that a large part of the processing time is spent in malloc/memcpy/free in the sample ordering code. That code copies the data from the mmap into malloc'ed memory. That's silly. We can keep the mmap and just store the pointer in the queuing data structure. For 64 bit this is not a problem as we map the whole file anyway. On 32bit we keep 8 maps around and unmap the oldest before mmaping the next chunk of the file. Performance gain: 2.95s -> 1.23s (Faktor 2.4) Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <20101130163820.278787719@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c27
1 files changed, 11 insertions, 16 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 752577fdb16e..c98958314102 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -418,7 +418,6 @@ static void flush_sample_queue(struct perf_session *s,
418 418
419 os->last_flush = iter->timestamp; 419 os->last_flush = iter->timestamp;
420 list_del(&iter->list); 420 list_del(&iter->list);
421 free(iter->event);
422 free(iter); 421 free(iter);
423 } 422 }
424 423
@@ -531,7 +530,6 @@ static int queue_sample_event(event_t *event, struct sample_data *data,
531 u64 timestamp = data->time; 530 u64 timestamp = data->time;
532 struct sample_queue *new; 531 struct sample_queue *new;
533 532
534
535 if (timestamp < s->ordered_samples.last_flush) { 533 if (timestamp < s->ordered_samples.last_flush) {
536 printf("Warning: Timestamp below last timeslice flush\n"); 534 printf("Warning: Timestamp below last timeslice flush\n");
537 return -EINVAL; 535 return -EINVAL;
@@ -542,14 +540,7 @@ static int queue_sample_event(event_t *event, struct sample_data *data,
542 return -ENOMEM; 540 return -ENOMEM;
543 541
544 new->timestamp = timestamp; 542 new->timestamp = timestamp;
545 543 new->event = event;
546 new->event = malloc(event->header.size);
547 if (!new->event) {
548 free(new);
549 return -ENOMEM;
550 }
551
552 memcpy(new->event, event, event->header.size);
553 544
554 __queue_sample_event(new, s); 545 __queue_sample_event(new, s);
555 546
@@ -747,12 +738,12 @@ int __perf_session__process_events(struct perf_session *session,
747 u64 file_size, struct perf_event_ops *ops) 738 u64 file_size, struct perf_event_ops *ops)
748{ 739{
749 u64 head, page_offset, file_offset, file_pos, progress_next; 740 u64 head, page_offset, file_offset, file_pos, progress_next;
750 int err, mmap_prot, mmap_flags; 741 int err, mmap_prot, mmap_flags, map_idx = 0;
751 struct ui_progress *progress; 742 struct ui_progress *progress;
752 size_t page_size, mmap_size; 743 size_t page_size, mmap_size;
744 char *buf, *mmaps[8];
753 event_t *event; 745 event_t *event;
754 uint32_t size; 746 uint32_t size;
755 char *buf;
756 747
757 perf_event_ops__fill_defaults(ops); 748 perf_event_ops__fill_defaults(ops);
758 749
@@ -774,6 +765,8 @@ int __perf_session__process_events(struct perf_session *session,
774 if (mmap_size > file_size) 765 if (mmap_size > file_size)
775 mmap_size = file_size; 766 mmap_size = file_size;
776 767
768 memset(mmaps, 0, sizeof(mmaps));
769
777 mmap_prot = PROT_READ; 770 mmap_prot = PROT_READ;
778 mmap_flags = MAP_SHARED; 771 mmap_flags = MAP_SHARED;
779 772
@@ -789,6 +782,8 @@ remap:
789 err = -errno; 782 err = -errno;
790 goto out_err; 783 goto out_err;
791 } 784 }
785 mmaps[map_idx] = buf;
786 map_idx = (map_idx + 1) & (ARRAY_SIZE(mmaps) - 1);
792 file_pos = file_offset + head; 787 file_pos = file_offset + head;
793 788
794more: 789more:
@@ -801,10 +796,10 @@ more:
801 size = 8; 796 size = 8;
802 797
803 if (head + event->header.size >= mmap_size) { 798 if (head + event->header.size >= mmap_size) {
804 int munmap_ret; 799 if (mmaps[map_idx]) {
805 800 munmap(mmaps[map_idx], mmap_size);
806 munmap_ret = munmap(buf, mmap_size); 801 mmaps[map_idx] = NULL;
807 assert(munmap_ret == 0); 802 }
808 803
809 page_offset = page_size * (head / page_size); 804 page_offset = page_size * (head / page_size);
810 file_offset += page_offset; 805 file_offset += page_offset;