aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Khlebnikov <khlebnikov@yandex-team.ru>2018-08-07 10:24:54 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2018-08-08 14:56:00 -0400
commit6a9405b56c274024564f9014bba97b92c91b34d6 (patch)
treeb0ea4a8e47bd597333ce636c7e89a9c9a026101a
parente5adfc3e7e774ba86f7bb725c6eef5f32df8630e (diff)
perf map: Optimize maps__fixup_overlappings()
This function splits and removes overlapping areas. Maps in tree are ordered by start address thus we could find first overlap and stop if next map does not overlap. Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/153365189407.435244.7234821822450484712.stgit@buzz Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/map.c44
-rw-r--r--tools/perf/util/map.h1
2 files changed, 26 insertions, 19 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 89ac5b5dc218..36d0763311ef 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -381,20 +381,6 @@ struct map *map__clone(struct map *from)
381 return map; 381 return map;
382} 382}
383 383
384int map__overlap(struct map *l, struct map *r)
385{
386 if (l->start > r->start) {
387 struct map *t = l;
388 l = r;
389 r = t;
390 }
391
392 if (l->end > r->start)
393 return 1;
394
395 return 0;
396}
397
398size_t map__fprintf(struct map *map, FILE *fp) 384size_t map__fprintf(struct map *map, FILE *fp)
399{ 385{
400 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", 386 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
@@ -675,20 +661,42 @@ static void __map_groups__insert(struct map_groups *mg, struct map *map)
675static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) 661static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
676{ 662{
677 struct rb_root *root; 663 struct rb_root *root;
678 struct rb_node *next; 664 struct rb_node *next, *first;
679 int err = 0; 665 int err = 0;
680 666
681 down_write(&maps->lock); 667 down_write(&maps->lock);
682 668
683 root = &maps->entries; 669 root = &maps->entries;
684 next = rb_first(root);
685 670
671 /*
672 * Find first map where end > map->start.
673 * Same as find_vma() in kernel.
674 */
675 next = root->rb_node;
676 first = NULL;
677 while (next) {
678 struct map *pos = rb_entry(next, struct map, rb_node);
679
680 if (pos->end > map->start) {
681 first = next;
682 if (pos->start <= map->start)
683 break;
684 next = next->rb_left;
685 } else
686 next = next->rb_right;
687 }
688
689 next = first;
686 while (next) { 690 while (next) {
687 struct map *pos = rb_entry(next, struct map, rb_node); 691 struct map *pos = rb_entry(next, struct map, rb_node);
688 next = rb_next(&pos->rb_node); 692 next = rb_next(&pos->rb_node);
689 693
690 if (!map__overlap(pos, map)) 694 /*
691 continue; 695 * Stop if current map starts after map->end.
696 * Maps are ordered by start: next will not overlap for sure.
697 */
698 if (pos->start >= map->end)
699 break;
692 700
693 if (verbose >= 2) { 701 if (verbose >= 2) {
694 702
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 4cb90f242bed..e0f327b51e66 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -166,7 +166,6 @@ static inline void __map__zput(struct map **map)
166 166
167#define map__zput(map) __map__zput(&map) 167#define map__zput(map) __map__zput(&map)
168 168
169int map__overlap(struct map *l, struct map *r);
170size_t map__fprintf(struct map *map, FILE *fp); 169size_t map__fprintf(struct map *map, FILE *fp);
171size_t map__fprintf_dsoname(struct map *map, FILE *fp); 170size_t map__fprintf_dsoname(struct map *map, FILE *fp);
172char *map__srcline(struct map *map, u64 addr, struct symbol *sym); 171char *map__srcline(struct map *map, u64 addr, struct symbol *sym);