Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Introduce struct maps

That for now has the maps rbtree and the list for the dead maps, that
may be still referenced from some hist_entry, etc.

This paves the way for protecting the rbtree with a lock, then refcount
the maps and finally remove the removed_maps list, as it'll not ne
anymore needed.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-fl0fa6142pj8khj97fow3uw0@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+52 -38
+1 -1
tools/perf/tests/vmlinux-kallsyms.c
··· 26 26 struct map *kallsyms_map, *vmlinux_map, *map; 27 27 struct machine kallsyms, vmlinux; 28 28 enum map_type type = MAP__FUNCTION; 29 - struct rb_root *maps = &vmlinux.kmaps.maps[type]; 29 + struct maps *maps = &vmlinux.kmaps.maps[type]; 30 30 u64 mem_start, mem_end; 31 31 32 32 /*
+1 -1
tools/perf/util/event.c
··· 331 331 int rc = 0; 332 332 struct map *pos; 333 333 struct map_groups *kmaps = &machine->kmaps; 334 - struct rb_root *maps = &kmaps->maps[MAP__FUNCTION]; 334 + struct maps *maps = &kmaps->maps[MAP__FUNCTION]; 335 335 union perf_event *event = zalloc((sizeof(event->mmap) + 336 336 machine->id_hdr_size)); 337 337 if (event == NULL) {
+37 -27
tools/perf/util/map.c
··· 418 418 return ip + map->reloc; 419 419 } 420 420 421 + static void maps__init(struct maps *maps) 422 + { 423 + maps->entries = RB_ROOT; 424 + INIT_LIST_HEAD(&maps->removed_maps); 425 + } 426 + 421 427 void map_groups__init(struct map_groups *mg, struct machine *machine) 422 428 { 423 429 int i; 424 430 for (i = 0; i < MAP__NR_TYPES; ++i) { 425 - mg->maps[i] = RB_ROOT; 426 - INIT_LIST_HEAD(&mg->removed_maps[i]); 431 + maps__init(&mg->maps[i]); 427 432 } 428 433 mg->machine = machine; 429 434 atomic_set(&mg->refcnt, 1); 430 435 } 431 436 432 - static void maps__delete(struct rb_root *maps) 437 + static void maps__purge(struct maps *maps) 433 438 { 434 - struct rb_node *next = rb_first(maps); 439 + struct rb_root *root = &maps->entries; 440 + struct rb_node *next = rb_first(root); 435 441 436 442 while (next) { 437 443 struct map *pos = rb_entry(next, struct map, rb_node); 438 444 439 445 next = rb_next(&pos->rb_node); 440 - rb_erase(&pos->rb_node, maps); 446 + rb_erase(&pos->rb_node, root); 441 447 map__delete(pos); 442 448 } 443 449 } 444 450 445 - static void maps__delete_removed(struct list_head *maps) 451 + static void maps__purge_removed_maps(struct maps *maps) 446 452 { 447 453 struct map *pos, *n; 448 454 449 - list_for_each_entry_safe(pos, n, maps, node) { 455 + list_for_each_entry_safe(pos, n, &maps->removed_maps, node) { 450 456 list_del(&pos->node); 451 457 map__delete(pos); 452 458 } 459 + } 460 + 461 + static void maps__exit(struct maps *maps) 462 + { 463 + maps__purge(maps); 464 + maps__purge_removed_maps(maps); 453 465 } 454 466 455 467 void map_groups__exit(struct map_groups *mg) 456 468 { 457 469 int i; 458 470 459 - for (i = 0; i < MAP__NR_TYPES; ++i) { 460 - maps__delete(&mg->maps[i]); 461 - maps__delete_removed(&mg->removed_maps[i]); 462 - } 471 + for (i = 0; i < MAP__NR_TYPES; ++i) 472 + maps__exit(&mg->maps[i]); 463 473 } 464 474 465 475 bool map_groups__empty(struct map_groups *mg) ··· 479 469 for (i = 0; i < MAP__NR_TYPES; ++i) { 480 470 if (maps__first(&mg->maps[i])) 481 471 return false; 482 - if (!list_empty(&mg->removed_maps[i])) 472 + if (!list_empty(&mg->maps[i].removed_maps)) 483 473 return false; 484 474 } 485 475 ··· 533 523 { 534 524 struct rb_node *nd; 535 525 536 - for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) { 526 + for (nd = rb_first(&mg->maps[type].entries); nd; nd = rb_next(nd)) { 537 527 struct map *pos = rb_entry(nd, struct map, rb_node); 538 528 struct symbol *sym = map__find_symbol_by_name(pos, name, filter); 539 529 ··· 570 560 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]); 571 561 struct rb_node *nd; 572 562 573 - for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) { 563 + for (nd = rb_first(&mg->maps[type].entries); nd; nd = rb_next(nd)) { 574 564 struct map *pos = rb_entry(nd, struct map, rb_node); 575 565 printed += fprintf(fp, "Map:"); 576 566 printed += map__fprintf(pos, fp); ··· 597 587 struct map *pos; 598 588 size_t printed = 0; 599 589 600 - list_for_each_entry(pos, &mg->removed_maps[type], node) { 590 + list_for_each_entry(pos, &mg->maps[type].removed_maps, node) { 601 591 printed += fprintf(fp, "Map:"); 602 592 printed += map__fprintf(pos, fp); 603 593 if (verbose > 1) { ··· 627 617 int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, 628 618 FILE *fp) 629 619 { 630 - struct rb_root *root = &mg->maps[map->type]; 620 + struct rb_root *root = &mg->maps[map->type].entries; 631 621 struct rb_node *next = rb_first(root); 632 622 int err = 0; 633 623 ··· 681 671 * If we have references, just move them to a separate list. 682 672 */ 683 673 if (pos->referenced) 684 - list_add_tail(&pos->node, &mg->removed_maps[map->type]); 674 + list_add_tail(&pos->node, &mg->maps[map->type].removed_maps); 685 675 else 686 676 map__delete(pos); 687 677 ··· 699 689 struct map_groups *parent, enum map_type type) 700 690 { 701 691 struct map *map; 702 - struct rb_root *maps = &parent->maps[type]; 692 + struct maps *maps = &parent->maps[type]; 703 693 704 694 for (map = maps__first(maps); map; map = map__next(map)) { 705 695 struct map *new = map__clone(map); ··· 710 700 return 0; 711 701 } 712 702 713 - void maps__insert(struct rb_root *maps, struct map *map) 703 + void maps__insert(struct maps *maps, struct map *map) 714 704 { 715 - struct rb_node **p = &maps->rb_node; 705 + struct rb_node **p = &maps->entries.rb_node; 716 706 struct rb_node *parent = NULL; 717 707 const u64 ip = map->start; 718 708 struct map *m; ··· 727 717 } 728 718 729 719 rb_link_node(&map->rb_node, parent, p); 730 - rb_insert_color(&map->rb_node, maps); 720 + rb_insert_color(&map->rb_node, &maps->entries); 731 721 } 732 722 733 - void maps__remove(struct rb_root *maps, struct map *map) 723 + void maps__remove(struct maps *maps, struct map *map) 734 724 { 735 - rb_erase(&map->rb_node, maps); 725 + rb_erase(&map->rb_node, &maps->entries); 736 726 } 737 727 738 - struct map *maps__find(struct rb_root *maps, u64 ip) 728 + struct map *maps__find(struct maps *maps, u64 ip) 739 729 { 740 - struct rb_node **p = &maps->rb_node; 730 + struct rb_node **p = &maps->entries.rb_node; 741 731 struct rb_node *parent = NULL; 742 732 struct map *m; 743 733 ··· 755 745 return NULL; 756 746 } 757 747 758 - struct map *maps__first(struct rb_root *maps) 748 + struct map *maps__first(struct maps *maps) 759 749 { 760 - struct rb_node *first = rb_first(maps); 750 + struct rb_node *first = rb_first(&maps->entries); 761 751 762 752 if (first) 763 753 return rb_entry(first, struct map, rb_node);
+10 -6
tools/perf/util/map.h
··· 58 58 struct map_groups *kmaps; 59 59 }; 60 60 61 + struct maps { 62 + struct rb_root entries; 63 + struct list_head removed_maps; 64 + }; 65 + 61 66 struct map_groups { 62 - struct rb_root maps[MAP__NR_TYPES]; 63 - struct list_head removed_maps[MAP__NR_TYPES]; 67 + struct maps maps[MAP__NR_TYPES]; 64 68 struct machine *machine; 65 69 atomic_t refcnt; 66 70 }; ··· 166 162 167 163 size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type, 168 164 FILE *fp); 169 - void maps__insert(struct rb_root *maps, struct map *map); 170 - void maps__remove(struct rb_root *maps, struct map *map); 171 - struct map *maps__find(struct rb_root *maps, u64 addr); 172 - struct map *maps__first(struct rb_root *maps); 165 + void maps__insert(struct maps *maps, struct map *map); 166 + void maps__remove(struct maps *maps, struct map *map); 167 + struct map *maps__find(struct maps *maps, u64 addr); 168 + struct map *maps__first(struct maps *maps); 173 169 struct map *map__next(struct map *map); 174 170 void map_groups__init(struct map_groups *mg, struct machine *machine); 175 171 void map_groups__exit(struct map_groups *mg);
+1 -1
tools/perf/util/probe-event.c
··· 163 163 static struct map *kernel_get_module_map(const char *module) 164 164 { 165 165 struct map_groups *grp = &host_machine->kmaps; 166 - struct rb_root *maps = &grp->maps[MAP__FUNCTION]; 166 + struct maps *maps = &grp->maps[MAP__FUNCTION]; 167 167 struct map *pos; 168 168 169 169 /* A file path -- this is an offline module */
+2 -2
tools/perf/util/symbol.c
··· 202 202 203 203 void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) 204 204 { 205 - struct rb_root *maps = &mg->maps[type]; 205 + struct maps *maps = &mg->maps[type]; 206 206 struct map *next, *curr; 207 207 208 208 curr = maps__first(maps); ··· 1520 1520 struct map *map_groups__find_by_name(struct map_groups *mg, 1521 1521 enum map_type type, const char *name) 1522 1522 { 1523 - struct rb_root *maps = &mg->maps[type]; 1523 + struct maps *maps = &mg->maps[type]; 1524 1524 struct map *map; 1525 1525 1526 1526 for (map = maps__first(maps); map; map = map__next(map)) {