diff options
author | 2023-04-19 10:48:37 -0300 | |
---|---|---|
committer | 2023-04-19 10:53:01 -0300 | |
commit | 8f12692b7e61e5fb5d3e4f6692d6675f62eeebdc (patch) | |
tree | c3c653ed2524b984c7b4ae279d6a096f344fd569 /tools/perf/util/maps.c | |
parent | perf maps: Use maps__nr_maps() instead of open coded maps->nr_maps (diff) | |
download | linux-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.c | 47 |
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) |