[PATCH v4 6/7] perf dso: Reference counting related fixes

Ian Rogers
2024-04-23T04:26:34Z

Ensure gets and puts are better aligned fixing reference couting
checking problems.

Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/util/machine.c | 4 +--
tools/perf/util/map.c | 1 +
tools/perf/util/symbol-elf.c | 51 ++++++++++++++++++------------------
3 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 0b8fb14f5ff6..4a4541a2e887 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -683,7 +683,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
struct perf_sample *sample __maybe_unused)
{
struct symbol *sym;
- struct dso *dso;
+ struct dso *dso = NULL;
struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
int err = 0;

@@ -696,7 +696,6 @@ static int machine__process_ksymbol_register(struct machine *machine,
}
dso__set_kernel(dso, DSO_SPACE__KERNEL);
map = map__new2(0, dso);
- dso__put(dso);
if (!map) {
err = -ENOMEM;
goto out;
@@ -735,6 +734,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
dso__insert_symbol(dso, sym);
out:
map__put(map);
+ dso__put(dso);
return err;
}

diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 117c4bb78b35..e1d14936a60d 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -200,6 +200,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
dso__set_build_id(dso, dso__bid(header_bid_dso));
dso__set_header_build_id(dso, 1);
}
+ dso__put(header_bid_dso);
}
dso__put(dso);
}
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 3be5e8d1e278..e398abfd13a0 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1419,7 +1419,7 @@ void __weak arch__sym_update(struct symbol *s __maybe_unused,
static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
GElf_Sym *sym, GElf_Shdr *shdr,
struct maps *kmaps, struct kmap *kmap,
- struct dso **curr_dsop, struct map **curr_mapp,
+ struct dso **curr_dsop,
const char *section_name,
bool adjust_kernel_syms, bool kmodule, bool *remap_kernel,
u64 max_text_sh_offset)
@@ -1470,8 +1470,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
map__set_pgoff(map, shdr->sh_offset);
}

- *curr_mapp = map;
- *curr_dsop = dso;
+ dso__put(*curr_dsop);
+ *curr_dsop = dso__get(dso);
return 0;
}

@@ -1484,8 +1484,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
*/
if (kmodule && adjust_kernel_syms && is_exe_text(shdr->sh_flags) &&
shdr->sh_offset <= max_text_sh_offset) {
- *curr_mapp = map;
- *curr_dsop = dso;
+ dso__put(*curr_dsop);
+ *curr_dsop = dso__get(dso);
return 0;
}

@@ -1507,10 +1507,10 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
dso__set_binary_type(curr_dso, dso__binary_type(dso));
dso__set_adjust_symbols(curr_dso, dso__adjust_symbols(dso));
curr_map = map__new2(start, curr_dso);
- dso__put(curr_dso);
- if (curr_map == NULL)
+ if (curr_map == NULL) {
+ dso__put(curr_dso);
return -1;
-
+ }
if (dso__kernel(curr_dso))
map__kmap(curr_map)->kmaps = kmaps;

@@ -1524,21 +1524,15 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
dso__set_symtab_type(curr_dso, dso__symtab_type(dso));
if (maps__insert(kmaps, curr_map))
return -1;
- /*
- * Add it before we drop the reference to curr_map, i.e. while
- * we still are sure to have a reference to this DSO via
- * *curr_map->dso.
- */
dsos__add(&maps__machine(kmaps)->dsos, curr_dso);
- /* kmaps already got it */
- map__put(curr_map);
dso__set_loaded(curr_dso);
- *curr_mapp = curr_map;
+ dso__put(*curr_dsop);
*curr_dsop = curr_dso;
} else {
- *curr_dsop = map__dso(curr_map);
- map__put(curr_map);
+ dso__put(*curr_dsop);
+ *curr_dsop = dso__get(map__dso(curr_map));
}
+ map__put(curr_map);

return 0;
}
@@ -1549,11 +1543,9 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
{
struct kmap *kmap = dso__kernel(dso) ? map__kmap(map) : NULL;
struct maps *kmaps = kmap ? map__kmaps(map) : NULL;
- struct map *curr_map = map;
- struct dso *curr_dso = dso;
+ struct dso *curr_dso = NULL;
Elf_Data *symstrs, *secstrs, *secstrs_run, *secstrs_sym;
uint32_t nr_syms;
- int err = -1;
uint32_t idx;
GElf_Ehdr ehdr;
GElf_Shdr shdr;
@@ -1656,6 +1648,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
if (kmodule && adjust_kernel_syms)
max_text_sh_offset = max_text_section(runtime_ss->elf, &runtime_ss->ehdr);

+ curr_dso = dso__get(dso);
elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
struct symbol *f;
const char *elf_name = elf_sym__name(&sym, symstrs);
@@ -1744,9 +1737,13 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
--sym.st_value;

if (dso__kernel(dso)) {
- if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map,
- section_name, adjust_kernel_syms, kmodule,
- &remap_kernel, max_text_sh_offset))
+ if (dso__process_kernel_symbol(dso, map, &sym, &shdr,
+ kmaps, kmap, &curr_dso,
+ section_name,
+ adjust_kernel_syms,
+ kmodule,
+ &remap_kernel,
+ max_text_sh_offset))
goto out_elf_end;
} else if ((used_opd && runtime_ss->adjust_symbols) ||
(!used_opd && syms_ss->adjust_symbols)) {
@@ -1795,6 +1792,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
__symbols__insert(dso__symbols(curr_dso), f, dso__kernel(dso));
nr++;
}
+ dso__put(curr_dso);

/*
* For misannotated, zeroed, ASM function sizes.
@@ -1810,9 +1808,10 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
maps__fixup_end(kmaps);
}
}
- err = nr;
+ return nr;
out_elf_end:
- return err;
+ dso__put(curr_dso);
+ return -1;
}

int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
--
2.44.0.769.g3c40516874-goog