summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/machine.c3
-rw-r--r--tools/perf/util/map.c21
-rw-r--r--tools/perf/util/map.h11
-rw-r--r--tools/perf/util/probe-event.c6
-rw-r--r--tools/perf/util/symbol-elf.c2
-rw-r--r--tools/perf/util/symbol.c7
6 files changed, 38 insertions, 12 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 6bf8457..0c0e61cc 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -759,7 +759,6 @@ void machine__destroy_kernel_maps(struct machine *machine)
kmap->ref_reloc_sym = NULL;
}
- map__delete(machine->vmlinux_maps[type]);
machine->vmlinux_maps[type] = NULL;
}
}
@@ -1247,6 +1246,7 @@ int machine__process_mmap2_event(struct machine *machine,
thread__insert_map(thread, map);
thread__put(thread);
+ map__put(map);
return 0;
out_problem_map:
@@ -1297,6 +1297,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
thread__insert_map(thread, map);
thread__put(thread);
+ map__put(map);
return 0;
out_problem_map:
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 4d3a92d..af57232 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)
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 6796f27..b8df09d 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -52,6 +52,7 @@ struct map {
struct dso *dso;
struct map_groups *groups;
+ atomic_t refcnt;
};
struct kmap {
@@ -150,6 +151,16 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
void map__delete(struct map *map);
struct map *map__clone(struct map *map);
+
+static inline struct map *map__get(struct map *map)
+{
+ if (map)
+ atomic_inc(&map->refcnt);
+ return map;
+}
+
+void map__put(struct map *map);
+
int map__overlap(struct map *l, struct map *r);
size_t map__fprintf(struct map *map, FILE *fp);
size_t map__fprintf_dsoname(struct map *map, FILE *fp);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 32471d0..b0b8a80 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -195,7 +195,7 @@ static void put_target_map(struct map *map, bool user)
{
if (map && user) {
/* Only the user map needs to be released */
- map__delete(map);
+ map__put(map);
}
}
@@ -1791,7 +1791,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
out:
if (map && !is_kprobe) {
- map__delete(map);
+ map__put(map);
}
return ret;
@@ -2884,7 +2884,7 @@ int show_available_funcs(const char *target, struct strfilter *_filter,
dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
end:
if (user) {
- map__delete(map);
+ map__put(map);
}
exit_symbol_maps();
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 9d526a5..fa10116 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -972,8 +972,10 @@ int dso__load_sym(struct dso *dso, struct map *map,
map->unmap_ip = map__unmap_ip;
/* Ensure maps are correctly ordered */
if (kmaps) {
+ map__get(map);
map_groups__remove(kmaps, map);
map_groups__insert(kmaps, map);
+ map__put(map);
}
}
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 743a9b3..a3e80d6 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1180,13 +1180,16 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
map->pgoff = new_map->pgoff;
map->map_ip = new_map->map_ip;
map->unmap_ip = new_map->unmap_ip;
- map__delete(new_map);
/* Ensure maps are correctly ordered */
+ map__get(map);
map_groups__remove(kmaps, map);
map_groups__insert(kmaps, map);
+ map__put(map);
} else {
map_groups__insert(kmaps, new_map);
}
+
+ map__put(new_map);
}
/*
@@ -1212,7 +1215,7 @@ out_err:
while (!list_empty(&md.maps)) {
map = list_entry(md.maps.next, struct map, node);
list_del_init(&map->node);
- map__delete(map);
+ map__put(map);
}
close(fd);
return -EINVAL;
OpenPOWER on IntegriCloud