aboutsummaryrefslogtreecommitdiff
path: root/tools/perf/util/maps.c
diff options
context:
space:
mode:
authorGravatar Ian Rogers <irogers@google.com> 2023-04-19 10:48:37 -0300
committerGravatar Arnaldo Carvalho de Melo <acme@redhat.com> 2023-04-19 10:53:01 -0300
commit8f12692b7e61e5fb5d3e4f6692d6675f62eeebdc (patch)
treec3c653ed2524b984c7b4ae279d6a096f344fd569 /tools/perf/util/maps.c
parentperf maps: Use maps__nr_maps() instead of open coded maps->nr_maps (diff)
downloadlinux-8f12692b7e61e5fb5d3e4f6692d6675f62eeebdc.tar.gz
linux-8f12692b7e61e5fb5d3e4f6692d6675f62eeebdc.tar.bz2
linux-8f12692b7e61e5fb5d3e4f6692d6675f62eeebdc.zip
perf maps: Add reference count checking
Add reference count checking to make sure of good use of get and put. Add and use accessors to reduce RC_CHK clutter. The only significant issue was in tests/thread-maps-share.c where reference counts were released in the reverse order to acquisition, leading to a use after put. This was fixed by reversing the put order. Committer notes: Extracted from a larger patch removing bits that were covered by the use of pre-existing maps__ accessors (e.g. maps__nr_maps()) and new ones added (maps__refcnt()) to reduce RC_CHK_ACCESS(maps)-> source code pollution. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexey Bayduraev <alexey.v.bayduraev@linux.intel.com> Cc: Dmitriy Vyukov <dvyukov@google.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Riccardo Mancini <rickyman7@gmail.com> Cc: Stephane Eranian <eranian@google.com> Cc: Stephen Brennan <stephen.s.brennan@oracle.com> Link: https://lore.kernel.org/lkml/20230407230405.2931830-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/maps.c')
-rw-r--r--tools/perf/util/maps.c47
1 files changed, 26 insertions, 21 deletions
diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
index 953dc20d55d7..8a13396acd1a 100644
--- a/tools/perf/util/maps.c
+++ b/tools/perf/util/maps.c
@@ -13,12 +13,12 @@
static void maps__init(struct maps *maps, struct machine *machine)
{
refcount_set(maps__refcnt(maps), 1);
- maps->entries = RB_ROOT;
init_rwsem(maps__lock(maps));
- maps->machine = machine;
- maps->last_search_by_name = NULL;
- maps->nr_maps = 0;
- maps->maps_by_name = NULL;
+ RC_CHK_ACCESS(maps)->entries = RB_ROOT;
+ RC_CHK_ACCESS(maps)->machine = machine;
+ RC_CHK_ACCESS(maps)->last_search_by_name = NULL;
+ RC_CHK_ACCESS(maps)->nr_maps = 0;
+ RC_CHK_ACCESS(maps)->maps_by_name = NULL;
}
static void __maps__free_maps_by_name(struct maps *maps)
@@ -29,8 +29,8 @@ static void __maps__free_maps_by_name(struct maps *maps)
for (unsigned int i = 0; i < maps__nr_maps(maps); i++)
map__put(maps__maps_by_name(maps)[i]);
- zfree(&maps->maps_by_name);
- maps->nr_maps_allocated = 0;
+ zfree(&RC_CHK_ACCESS(maps)->maps_by_name);
+ RC_CHK_ACCESS(maps)->nr_maps_allocated = 0;
}
static int __maps__insert(struct maps *maps, struct map *map)
@@ -71,7 +71,7 @@ int maps__insert(struct maps *maps, struct map *map)
if (err)
goto out;
- ++maps->nr_maps;
+ ++RC_CHK_ACCESS(maps)->nr_maps;
if (dso && dso->kernel) {
struct kmap *kmap = map__kmap(map);
@@ -88,7 +88,7 @@ int maps__insert(struct maps *maps, struct map *map)
* inserted map and resort.
*/
if (maps__maps_by_name(maps)) {
- if (maps__nr_maps(maps) > maps->nr_maps_allocated) {
+ if (maps__nr_maps(maps) > RC_CHK_ACCESS(maps)->nr_maps_allocated) {
int nr_allocate = maps__nr_maps(maps) * 2;
struct map **maps_by_name = realloc(maps__maps_by_name(maps),
nr_allocate * sizeof(map));
@@ -99,8 +99,8 @@ int maps__insert(struct maps *maps, struct map *map)
goto out;
}
- maps->maps_by_name = maps_by_name;
- maps->nr_maps_allocated = nr_allocate;
+ RC_CHK_ACCESS(maps)->maps_by_name = maps_by_name;
+ RC_CHK_ACCESS(maps)->nr_maps_allocated = nr_allocate;
}
maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] = map__get(map);
__maps__sort_by_name(maps);
@@ -122,15 +122,15 @@ void maps__remove(struct maps *maps, struct map *map)
struct map_rb_node *rb_node;
down_write(maps__lock(maps));
- if (maps->last_search_by_name == map)
- maps->last_search_by_name = NULL;
+ if (RC_CHK_ACCESS(maps)->last_search_by_name == map)
+ RC_CHK_ACCESS(maps)->last_search_by_name = NULL;
rb_node = maps__find_node(maps, map);
assert(rb_node->map == map);
__maps__remove(maps, rb_node);
if (maps__maps_by_name(maps))
__maps__free_maps_by_name(maps);
- --maps->nr_maps;
+ --RC_CHK_ACCESS(maps)->nr_maps;
up_write(maps__lock(maps));
}
@@ -162,33 +162,38 @@ bool maps__empty(struct maps *maps)
struct maps *maps__new(struct machine *machine)
{
- struct maps *maps = zalloc(sizeof(*maps));
+ struct maps *result;
+ RC_STRUCT(maps) *maps = zalloc(sizeof(*maps));
- if (maps != NULL)
- maps__init(maps, machine);
+ if (ADD_RC_CHK(result, maps))
+ maps__init(result, machine);
- return maps;
+ return result;
}
void maps__delete(struct maps *maps)
{
maps__exit(maps);
unwind__finish_access(maps);
- free(maps);
+ RC_CHK_FREE(maps);
}
struct maps *maps__get(struct maps *maps)
{
- if (maps)
+ struct maps *result;
+
+ if (RC_CHK_GET(result, maps))
refcount_inc(maps__refcnt(maps));
- return maps;
+ return result;
}
void maps__put(struct maps *maps)
{
if (maps && refcount_dec_and_test(maps__refcnt(maps)))
maps__delete(maps);
+ else
+ RC_CHK_PUT(maps);
}
struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp)