diff options
| author | Konstantin Khlebnikov <khlebnikov@yandex-team.ru> | 2018-08-07 10:24:54 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-08-08 14:56:00 -0400 |
| commit | 6a9405b56c274024564f9014bba97b92c91b34d6 (patch) | |
| tree | b0ea4a8e47bd597333ce636c7e89a9c9a026101a /tools/perf | |
| parent | e5adfc3e7e774ba86f7bb725c6eef5f32df8630e (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>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/util/map.c | 44 | ||||
| -rw-r--r-- | tools/perf/util/map.h | 1 |
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 | ||
| 384 | int 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 | |||
| 398 | size_t map__fprintf(struct map *map, FILE *fp) | 384 | size_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) | |||
| 675 | static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) | 661 | static 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 | ||
| 169 | int map__overlap(struct map *l, struct map *r); | ||
| 170 | size_t map__fprintf(struct map *map, FILE *fp); | 169 | size_t map__fprintf(struct map *map, FILE *fp); |
| 171 | size_t map__fprintf_dsoname(struct map *map, FILE *fp); | 170 | size_t map__fprintf_dsoname(struct map *map, FILE *fp); |
| 172 | char *map__srcline(struct map *map, u64 addr, struct symbol *sym); | 171 | char *map__srcline(struct map *map, u64 addr, struct symbol *sym); |
