Skip to content

Commit

Permalink
perf tools: Introduce struct maps
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Arnaldo Carvalho de Melo committed May 27, 2015
1 parent 6632c4b commit 1eee78a
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 38 deletions.
2 changes: 1 addition & 1 deletion tools/perf/tests/vmlinux-kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ int test__vmlinux_matches_kallsyms(void)
struct map *kallsyms_map, *vmlinux_map, *map;
struct machine kallsyms, vmlinux;
enum map_type type = MAP__FUNCTION;
struct rb_root *maps = &vmlinux.kmaps.maps[type];
struct maps *maps = &vmlinux.kmaps.maps[type];
u64 mem_start, mem_end;

/*
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool,
int rc = 0;
struct map *pos;
struct map_groups *kmaps = &machine->kmaps;
struct rb_root *maps = &kmaps->maps[MAP__FUNCTION];
struct maps *maps = &kmaps->maps[MAP__FUNCTION];
union perf_event *event = zalloc((sizeof(event->mmap) +
machine->id_hdr_size));
if (event == NULL) {
Expand Down
64 changes: 37 additions & 27 deletions tools/perf/util/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,48 +418,58 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
return ip + map->reloc;
}

static void maps__init(struct maps *maps)
{
maps->entries = RB_ROOT;
INIT_LIST_HEAD(&maps->removed_maps);
}

void map_groups__init(struct map_groups *mg, struct machine *machine)
{
int i;
for (i = 0; i < MAP__NR_TYPES; ++i) {
mg->maps[i] = RB_ROOT;
INIT_LIST_HEAD(&mg->removed_maps[i]);
maps__init(&mg->maps[i]);
}
mg->machine = machine;
atomic_set(&mg->refcnt, 1);
}

static void maps__delete(struct rb_root *maps)
static void maps__purge(struct maps *maps)
{
struct rb_node *next = rb_first(maps);
struct rb_root *root = &maps->entries;
struct rb_node *next = rb_first(root);

while (next) {
struct map *pos = rb_entry(next, struct map, rb_node);

next = rb_next(&pos->rb_node);
rb_erase(&pos->rb_node, maps);
rb_erase(&pos->rb_node, root);
map__delete(pos);
}
}

static void maps__delete_removed(struct list_head *maps)
static void maps__purge_removed_maps(struct maps *maps)
{
struct map *pos, *n;

list_for_each_entry_safe(pos, n, maps, node) {
list_for_each_entry_safe(pos, n, &maps->removed_maps, node) {
list_del(&pos->node);
map__delete(pos);
}
}

static void maps__exit(struct maps *maps)
{
maps__purge(maps);
maps__purge_removed_maps(maps);
}

void map_groups__exit(struct map_groups *mg)
{
int i;

for (i = 0; i < MAP__NR_TYPES; ++i) {
maps__delete(&mg->maps[i]);
maps__delete_removed(&mg->removed_maps[i]);
}
for (i = 0; i < MAP__NR_TYPES; ++i)
maps__exit(&mg->maps[i]);
}

bool map_groups__empty(struct map_groups *mg)
Expand All @@ -469,7 +479,7 @@ bool map_groups__empty(struct map_groups *mg)
for (i = 0; i < MAP__NR_TYPES; ++i) {
if (maps__first(&mg->maps[i]))
return false;
if (!list_empty(&mg->removed_maps[i]))
if (!list_empty(&mg->maps[i].removed_maps))
return false;
}

Expand Down Expand Up @@ -523,7 +533,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
{
struct rb_node *nd;

for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
for (nd = rb_first(&mg->maps[type].entries); nd; nd = rb_next(nd)) {
struct map *pos = rb_entry(nd, struct map, rb_node);
struct symbol *sym = map__find_symbol_by_name(pos, name, filter);

Expand Down Expand Up @@ -560,7 +570,7 @@ size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
struct rb_node *nd;

for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
for (nd = rb_first(&mg->maps[type].entries); nd; nd = rb_next(nd)) {
struct map *pos = rb_entry(nd, struct map, rb_node);
printed += fprintf(fp, "Map:");
printed += map__fprintf(pos, fp);
Expand All @@ -587,7 +597,7 @@ static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
struct map *pos;
size_t printed = 0;

list_for_each_entry(pos, &mg->removed_maps[type], node) {
list_for_each_entry(pos, &mg->maps[type].removed_maps, node) {
printed += fprintf(fp, "Map:");
printed += map__fprintf(pos, fp);
if (verbose > 1) {
Expand Down Expand Up @@ -617,7 +627,7 @@ size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
FILE *fp)
{
struct rb_root *root = &mg->maps[map->type];
struct rb_root *root = &mg->maps[map->type].entries;
struct rb_node *next = rb_first(root);
int err = 0;

Expand Down Expand Up @@ -671,7 +681,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
* If we have references, just move them to a separate list.
*/
if (pos->referenced)
list_add_tail(&pos->node, &mg->removed_maps[map->type]);
list_add_tail(&pos->node, &mg->maps[map->type].removed_maps);
else
map__delete(pos);

Expand All @@ -689,7 +699,7 @@ int map_groups__clone(struct map_groups *mg,
struct map_groups *parent, enum map_type type)
{
struct map *map;
struct rb_root *maps = &parent->maps[type];
struct maps *maps = &parent->maps[type];

for (map = maps__first(maps); map; map = map__next(map)) {
struct map *new = map__clone(map);
Expand All @@ -700,9 +710,9 @@ int map_groups__clone(struct map_groups *mg,
return 0;
}

void maps__insert(struct rb_root *maps, struct map *map)
void maps__insert(struct maps *maps, struct map *map)
{
struct rb_node **p = &maps->rb_node;
struct rb_node **p = &maps->entries.rb_node;
struct rb_node *parent = NULL;
const u64 ip = map->start;
struct map *m;
Expand All @@ -717,17 +727,17 @@ void maps__insert(struct rb_root *maps, struct map *map)
}

rb_link_node(&map->rb_node, parent, p);
rb_insert_color(&map->rb_node, maps);
rb_insert_color(&map->rb_node, &maps->entries);
}

void maps__remove(struct rb_root *maps, struct map *map)
void maps__remove(struct maps *maps, struct map *map)
{
rb_erase(&map->rb_node, maps);
rb_erase(&map->rb_node, &maps->entries);
}

struct map *maps__find(struct rb_root *maps, u64 ip)
struct map *maps__find(struct maps *maps, u64 ip)
{
struct rb_node **p = &maps->rb_node;
struct rb_node **p = &maps->entries.rb_node;
struct rb_node *parent = NULL;
struct map *m;

Expand All @@ -745,9 +755,9 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
return NULL;
}

struct map *maps__first(struct rb_root *maps)
struct map *maps__first(struct maps *maps)
{
struct rb_node *first = rb_first(maps);
struct rb_node *first = rb_first(&maps->entries);

if (first)
return rb_entry(first, struct map, rb_node);
Expand Down
16 changes: 10 additions & 6 deletions tools/perf/util/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,13 @@ struct kmap {
struct map_groups *kmaps;
};

struct maps {
struct rb_root entries;
struct list_head removed_maps;
};

struct map_groups {
struct rb_root maps[MAP__NR_TYPES];
struct list_head removed_maps[MAP__NR_TYPES];
struct maps maps[MAP__NR_TYPES];
struct machine *machine;
atomic_t refcnt;
};
Expand Down Expand Up @@ -162,10 +166,10 @@ void map__reloc_vmlinux(struct map *map);

size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
FILE *fp);
void maps__insert(struct rb_root *maps, struct map *map);
void maps__remove(struct rb_root *maps, struct map *map);
struct map *maps__find(struct rb_root *maps, u64 addr);
struct map *maps__first(struct rb_root *maps);
void maps__insert(struct maps *maps, struct map *map);
void maps__remove(struct maps *maps, struct map *map);
struct map *maps__find(struct maps *maps, u64 addr);
struct map *maps__first(struct maps *maps);
struct map *map__next(struct map *map);
void map_groups__init(struct map_groups *mg, struct machine *machine);
void map_groups__exit(struct map_groups *mg);
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/probe-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ static u64 kernel_get_symbol_address_by_name(const char *name, bool reloc)
static struct map *kernel_get_module_map(const char *module)
{
struct map_groups *grp = &host_machine->kmaps;
struct rb_root *maps = &grp->maps[MAP__FUNCTION];
struct maps *maps = &grp->maps[MAP__FUNCTION];
struct map *pos;

/* A file path -- this is an offline module */
Expand Down
4 changes: 2 additions & 2 deletions tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ void symbols__fixup_end(struct rb_root *symbols)

void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
{
struct rb_root *maps = &mg->maps[type];
struct maps *maps = &mg->maps[type];
struct map *next, *curr;

curr = maps__first(maps);
Expand Down Expand Up @@ -1520,7 +1520,7 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
struct map *map_groups__find_by_name(struct map_groups *mg,
enum map_type type, const char *name)
{
struct rb_root *maps = &mg->maps[type];
struct maps *maps = &mg->maps[type];
struct map *map;

for (map = maps__first(maps); map; map = map__next(map)) {
Expand Down

0 comments on commit 1eee78a

Please sign in to comment.