From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org,
Arnaldo Carvalho de Melo <acme@redhat.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Borislav Petkov <bp@suse.de>, David Ahern <dsahern@gmail.com>,
Don Zickus <dzickus@redhat.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Jiri Olsa <jolsa@redhat.com>, Namhyung Kim <namhyung@kernel.org>,
Stephane Eranian <eranian@google.com>
Subject: [PATCH 4/7] perf tools: Reference count struct map
Date: Wed, 27 May 2015 21:05:31 -0300 [thread overview]
Message-ID: <1432771534-1312-5-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1432771534-1312-1-git-send-email-acme@kernel.org>
From: Arnaldo Carvalho de Melo <acme@redhat.com>
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>
---
tools/perf/util/machine.c | 3 ++-
tools/perf/util/map.c | 21 +++++++++++++++------
tools/perf/util/map.h | 11 +++++++++++
tools/perf/util/probe-event.c | 6 +++---
tools/perf/util/symbol-elf.c | 2 ++
tools/perf/util/symbol.c | 7 +++++--
6 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 6bf845758ae3..0c0e61cce577 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 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)
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 6796f2785649..b8df09d94aca 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 32471d0839d1..b0b8a8080009 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 9d526a5312b1..fa10116a12ab 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 743a9b360e3d..a3e80d6ad70a 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;
--
2.1.0
next prev parent reply other threads:[~2015-05-28 0:06 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-28 0:05 [GIT PULL 0/7] perf/core refactorings and improvements Arnaldo Carvalho de Melo
2015-05-28 0:05 ` [PATCH 1/7] perf tools: Introduce struct maps Arnaldo Carvalho de Melo
2015-05-28 0:05 ` [PATCH 2/7] perf tools: Protect accesses the map rbtrees with a rw lock Arnaldo Carvalho de Melo
2015-05-28 0:05 ` [PATCH 3/7] perf tools: Check if a map is still in use when deleting it Arnaldo Carvalho de Melo
2015-05-28 0:05 ` Arnaldo Carvalho de Melo [this message]
2015-05-28 0:05 ` [PATCH 5/7] perf tools: Add hint for 'Too many events are opened.' error message Arnaldo Carvalho de Melo
2015-05-28 0:05 ` [PATCH 6/7] perf annotation: Add symbol__get_annotation Arnaldo Carvalho de Melo
2015-05-28 0:05 ` [PATCH 7/7] perf tools: Move branch option parsing to own file Arnaldo Carvalho de Melo
2015-05-28 0:27 ` [GIT PULL 0/7] perf/core refactorings and improvements Arnaldo Carvalho de Melo
2015-05-28 9:27 ` Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1432771534-1312-5-git-send-email-acme@kernel.org \
--to=acme@kernel.org \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=bp@suse.de \
--cc=dsahern@gmail.com \
--cc=dzickus@redhat.com \
--cc=eranian@google.com \
--cc=fweisbec@gmail.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).