Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf symbol-elf: dso__load_sym_internal() reference count fixes

dso__load_sym_internal() passed curr_mapp as an out argument to
dso__process_kernel_symbol(). The out argument was never used so remove
it to simplify the reference counting logic.

Simplify reference counting issues with curr_dso by ensuring the value
it points to has a +1 reference count, and then putting as
necessary.

This avoids some reference counting games when the dso is created making
the code more obviously correct with some possible introduced overhead
due to the reference counting get/puts.

This, however, silences reference count checking and we can always
optimize from a seemingly correct point.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Link: https://lore.kernel.org/r/20240506180104.485674-4-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
23106e31 ee5061f8

+25 -26
+25 -26
tools/perf/util/symbol-elf.c
··· 1419 1419 static int dso__process_kernel_symbol(struct dso *dso, struct map *map, 1420 1420 GElf_Sym *sym, GElf_Shdr *shdr, 1421 1421 struct maps *kmaps, struct kmap *kmap, 1422 - struct dso **curr_dsop, struct map **curr_mapp, 1422 + struct dso **curr_dsop, 1423 1423 const char *section_name, 1424 1424 bool adjust_kernel_syms, bool kmodule, bool *remap_kernel, 1425 1425 u64 max_text_sh_offset) ··· 1470 1470 map__set_pgoff(map, shdr->sh_offset); 1471 1471 } 1472 1472 1473 - *curr_mapp = map; 1474 - *curr_dsop = dso; 1473 + dso__put(*curr_dsop); 1474 + *curr_dsop = dso__get(dso); 1475 1475 return 0; 1476 1476 } 1477 1477 ··· 1484 1484 */ 1485 1485 if (kmodule && adjust_kernel_syms && is_exe_text(shdr->sh_flags) && 1486 1486 shdr->sh_offset <= max_text_sh_offset) { 1487 - *curr_mapp = map; 1488 - *curr_dsop = dso; 1487 + dso__put(*curr_dsop); 1488 + *curr_dsop = dso__get(dso); 1489 1489 return 0; 1490 1490 } 1491 1491 ··· 1507 1507 dso__set_binary_type(curr_dso, dso__binary_type(dso)); 1508 1508 dso__set_adjust_symbols(curr_dso, dso__adjust_symbols(dso)); 1509 1509 curr_map = map__new2(start, curr_dso); 1510 - dso__put(curr_dso); 1511 - if (curr_map == NULL) 1510 + if (curr_map == NULL) { 1511 + dso__put(curr_dso); 1512 1512 return -1; 1513 - 1513 + } 1514 1514 if (dso__kernel(curr_dso)) 1515 1515 map__kmap(curr_map)->kmaps = kmaps; 1516 1516 ··· 1524 1524 dso__set_symtab_type(curr_dso, dso__symtab_type(dso)); 1525 1525 if (maps__insert(kmaps, curr_map)) 1526 1526 return -1; 1527 - /* 1528 - * Add it before we drop the reference to curr_map, i.e. while 1529 - * we still are sure to have a reference to this DSO via 1530 - * *curr_map->dso. 1531 - */ 1532 1527 dsos__add(&maps__machine(kmaps)->dsos, curr_dso); 1533 - /* kmaps already got it */ 1534 - map__put(curr_map); 1535 1528 dso__set_loaded(curr_dso); 1536 - *curr_mapp = curr_map; 1529 + dso__put(*curr_dsop); 1537 1530 *curr_dsop = curr_dso; 1538 1531 } else { 1539 - *curr_dsop = map__dso(curr_map); 1540 - map__put(curr_map); 1532 + dso__put(*curr_dsop); 1533 + *curr_dsop = dso__get(map__dso(curr_map)); 1541 1534 } 1535 + map__put(curr_map); 1542 1536 1543 1537 return 0; 1544 1538 } ··· 1543 1549 { 1544 1550 struct kmap *kmap = dso__kernel(dso) ? map__kmap(map) : NULL; 1545 1551 struct maps *kmaps = kmap ? map__kmaps(map) : NULL; 1546 - struct map *curr_map = map; 1547 - struct dso *curr_dso = dso; 1552 + struct dso *curr_dso = NULL; 1548 1553 Elf_Data *symstrs, *secstrs, *secstrs_run, *secstrs_sym; 1549 1554 uint32_t nr_syms; 1550 - int err = -1; 1551 1555 uint32_t idx; 1552 1556 GElf_Ehdr ehdr; 1553 1557 GElf_Shdr shdr; ··· 1648 1656 if (kmodule && adjust_kernel_syms) 1649 1657 max_text_sh_offset = max_text_section(runtime_ss->elf, &runtime_ss->ehdr); 1650 1658 1659 + curr_dso = dso__get(dso); 1651 1660 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 1652 1661 struct symbol *f; 1653 1662 const char *elf_name = elf_sym__name(&sym, symstrs); ··· 1737 1744 --sym.st_value; 1738 1745 1739 1746 if (dso__kernel(dso)) { 1740 - if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map, 1741 - section_name, adjust_kernel_syms, kmodule, 1742 - &remap_kernel, max_text_sh_offset)) 1747 + if (dso__process_kernel_symbol(dso, map, &sym, &shdr, 1748 + kmaps, kmap, &curr_dso, 1749 + section_name, 1750 + adjust_kernel_syms, 1751 + kmodule, 1752 + &remap_kernel, 1753 + max_text_sh_offset)) 1743 1754 goto out_elf_end; 1744 1755 } else if ((used_opd && runtime_ss->adjust_symbols) || 1745 1756 (!used_opd && syms_ss->adjust_symbols)) { ··· 1792 1795 __symbols__insert(dso__symbols(curr_dso), f, dso__kernel(dso)); 1793 1796 nr++; 1794 1797 } 1798 + dso__put(curr_dso); 1795 1799 1796 1800 /* 1797 1801 * For misannotated, zeroed, ASM function sizes. ··· 1808 1810 maps__fixup_end(kmaps); 1809 1811 } 1810 1812 } 1811 - err = nr; 1813 + return nr; 1812 1814 out_elf_end: 1813 - return err; 1815 + dso__put(curr_dso); 1816 + return -1; 1814 1817 } 1815 1818 1816 1819 int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,