aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/map.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2015-05-25 16:59:56 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-05-27 20:27:30 -0300
commit84c2cafa288939e11d21c7830e32b2aee21b723e (patch)
tree237bef793c61dbb04a090e9bb750f197c5429b39 /tools/perf/util/map.c
parentperf tools: Check if a map is still in use when deleting it (diff)
downloadlinux-dev-84c2cafa288939e11d21c7830e32b2aee21b723e.tar.xz
linux-dev-84c2cafa288939e11d21c7830e32b2aee21b723e.zip
perf tools: Reference count struct map
We have pointers to struct map instances in several places, like in the hist_entry instances, so we need a way to know when we can destroy them, otherwise we may either keep leaking them or end up referencing deleted instances. Start fixing it by reference counting them. This patch puts the reference count for struct map in place, replacing direct map__delete() calls with map__put() ones and then grabbing a reference count when adding it to the maps struct where maps for a struct thread are kept. Next we'll grab reference counts when setting pointers to struct map instances, in places like in the hist_entry code. 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-wi19xczk0t2a41r1i2chuio5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r--tools/perf/util/map.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 4d3a92d5dff3..af572322586d 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -139,6 +139,7 @@ void map__init(struct map *map, enum map_type type,
map->groups = NULL;
map->referenced = false;
map->erange_warned = false;
+ atomic_set(&map->refcnt, 1);
}
struct map *map__new(struct machine *machine, u64 start, u64 len,
@@ -229,6 +230,12 @@ void map__delete(struct map *map)
free(map);
}
+void map__put(struct map *map)
+{
+ if (map && atomic_dec_and_test(&map->refcnt))
+ map__delete(map);
+}
+
void map__fixup_start(struct map *map)
{
struct rb_root *symbols = &map->dso->symbols[map->type];
@@ -448,7 +455,7 @@ static void __maps__purge(struct maps *maps)
next = rb_next(&pos->rb_node);
rb_erase_init(&pos->rb_node, root);
- map__delete(pos);
+ map__put(pos);
}
}
@@ -458,7 +465,7 @@ static void __maps__purge_removed_maps(struct maps *maps)
list_for_each_entry_safe(pos, n, &maps->removed_maps, node) {
list_del_init(&pos->node);
- map__delete(pos);
+ map__put(pos);
}
}
@@ -682,7 +689,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
if (before == NULL) {
err = -ENOMEM;
- goto move_map;
+ goto put_map;
}
before->end = map->start;
@@ -696,7 +703,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
if (after == NULL) {
err = -ENOMEM;
- goto move_map;
+ goto put_map;
}
after->start = map->end;
@@ -704,14 +711,14 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
if (verbose >= 2)
map__fprintf(after, fp);
}
-move_map:
+put_map:
/*
* If we have references, just move them to a separate list.
*/
if (pos->referenced)
list_add_tail(&pos->node, &maps->removed_maps);
else
- map__delete(pos);
+ map__put(pos);
if (err)
goto out;
@@ -772,6 +779,7 @@ static void __maps__insert(struct maps *maps, struct map *map)
rb_link_node(&map->rb_node, parent, p);
rb_insert_color(&map->rb_node, &maps->entries);
+ map__get(map);
}
void maps__insert(struct maps *maps, struct map *map)
@@ -784,6 +792,7 @@ void maps__insert(struct maps *maps, struct map *map)
static void __maps__remove(struct maps *maps, struct map *map)
{
rb_erase_init(&map->rb_node, &maps->entries);
+ map__put(map);
}
void maps__remove(struct maps *maps, struct map *map)