perf map: Add set_ methods for map->{start,end,pgoff,pgoff,reloc,erange_warned,dso,map_ip,unmap_ip,priv}

To have a way to intercept usage of the reference counted struct map.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2023-04-19 12:24:12 -03:00
parent e1805aae1e
commit e6a9efcee5
9 changed files with 132 additions and 65 deletions

View File

@ -191,7 +191,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
if (use_browser <= 0)
sleep(5);
map->erange_warned = true;
map__set_erange_warned(map, true);
}
static void perf_top__record_precise_ip(struct perf_top *top,
@ -225,7 +225,7 @@ static void perf_top__record_precise_ip(struct perf_top *top,
*/
mutex_unlock(&he->hists->lock);
if (err == -ERANGE && !he->ms.map->erange_warned)
if (err == -ERANGE && !map__erange_warned(he->ms.map))
ui__warn_map_erange(he->ms.map, sym, ip);
else if (err == -ENOMEM) {
pr_err("Not enough memory for annotating '%s' symbol!\n",

View File

@ -95,8 +95,8 @@ static int test__maps__merge_in(struct test_suite *t __maybe_unused, int subtest
map = dso__new_map(bpf_progs[i].name);
TEST_ASSERT_VAL("failed to create map", map);
map->start = bpf_progs[i].start;
map->end = bpf_progs[i].end;
map__set_start(map, bpf_progs[i].start);
map__set_end(map, bpf_progs[i].end);
TEST_ASSERT_VAL("failed to insert map", maps__insert(maps, map) == 0);
map__put(map);
}
@ -111,16 +111,16 @@ static int test__maps__merge_in(struct test_suite *t __maybe_unused, int subtest
TEST_ASSERT_VAL("failed to create map", map_kcore3);
/* kcore1 map overlaps over all bpf maps */
map_kcore1->start = 100;
map_kcore1->end = 1000;
map__set_start(map_kcore1, 100);
map__set_end(map_kcore1, 1000);
/* kcore2 map hides behind bpf_prog_2 */
map_kcore2->start = 550;
map_kcore2->end = 570;
map__set_start(map_kcore2, 550);
map__set_end(map_kcore2, 570);
/* kcore3 map hides behind bpf_prog_3, kcore1 and adds new map */
map_kcore3->start = 880;
map_kcore3->end = 1100;
map__set_start(map_kcore3, 880);
map__set_end(map_kcore3, 1100);
ret = maps__merge_in(maps, map_kcore1);
TEST_ASSERT_VAL("failed to merge map", !ret);

View File

@ -304,7 +304,7 @@ next_pair:
dso->short_name :
dso->name));
if (pair) {
pair->priv = 1;
map__set_priv(pair, 1);
} else {
if (!header_printed) {
pr_info("WARN: Maps only in vmlinux:\n");
@ -340,7 +340,7 @@ next_pair:
pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64,
map__start(pair), map__end(pair), map__pgoff(pair));
pr_info(" %s\n", dso->name);
pair->priv = 1;
map__set_priv(pair, 1);
}
}

View File

@ -910,8 +910,8 @@ static int machine__process_ksymbol_register(struct machine *machine,
dso__set_loaded(dso);
}
map->start = event->ksymbol.addr;
map->end = map__start(map) + event->ksymbol.len;
map__set_start(map, event->ksymbol.addr);
map__set_end(map, map__start(map) + event->ksymbol.len);
err = maps__insert(machine__kernel_maps(machine), map);
if (err) {
err = -ENOMEM;
@ -1218,8 +1218,8 @@ int machine__create_extra_kernel_map(struct machine *machine,
if (!map)
return -ENOMEM;
map->end = xm->end;
map->pgoff = xm->pgoff;
map__set_end(map, xm->end);
map__set_pgoff(map, xm->pgoff);
kmap = map__kmap(map);
@ -1291,7 +1291,7 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine,
dest_map = maps__find(kmaps, map__pgoff(map));
if (dest_map != map)
map->pgoff = map__map_ip(dest_map, map__pgoff(map));
map__set_pgoff(map, map__map_ip(dest_map, map__pgoff(map)));
found = true;
}
if (found || machine->trampolines_mapped)
@ -1342,7 +1342,8 @@ __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
if (machine->vmlinux_map == NULL)
return -ENOMEM;
machine->vmlinux_map->map_ip = machine->vmlinux_map->unmap_ip = identity__map_ip;
map__set_map_ip(machine->vmlinux_map, identity__map_ip);
map__set_unmap_ip(machine->vmlinux_map, identity__map_ip);
return maps__insert(machine__kernel_maps(machine), machine->vmlinux_map);
}
@ -1623,7 +1624,7 @@ static int machine__create_module(void *arg, const char *name, u64 start,
map = machine__addnew_module_map(machine, start, name);
if (map == NULL)
return -1;
map->end = start + size;
map__set_end(map, start + size);
dso__kernel_module_get_build_id(map__dso(map), machine->root_dir);
map__put(map);
@ -1659,14 +1660,14 @@ static int machine__create_modules(struct machine *machine)
static void machine__set_kernel_mmap(struct machine *machine,
u64 start, u64 end)
{
machine->vmlinux_map->start = start;
machine->vmlinux_map->end = end;
map__set_start(machine->vmlinux_map, start);
map__set_end(machine->vmlinux_map, end);
/*
* Be a bit paranoid here, some perf.data file came with
* a zero sized synthesized MMAP event for the kernel.
*/
if (start == 0 && end == 0)
machine->vmlinux_map->end = ~0ULL;
map__set_end(machine->vmlinux_map, ~0ULL);
}
static int machine__update_kernel_mmap(struct machine *machine,
@ -1810,7 +1811,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
if (map == NULL)
goto out_problem;
map->end = map__start(map) + xm->end - xm->start;
map__set_end(map, map__start(map) + xm->end - xm->start);
if (build_id__is_defined(bid))
dso__set_build_id(map__dso(map), bid);

View File

@ -104,14 +104,14 @@ static inline bool replace_android_lib(const char *filename, char *newfilename)
void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso)
{
map->start = start;
map->end = end;
map->pgoff = pgoff;
map->reloc = 0;
map->dso = dso__get(dso);
map->map_ip = map__dso_map_ip;
map->unmap_ip = map__dso_unmap_ip;
map->erange_warned = false;
map__set_start(map, start);
map__set_end(map, end);
map__set_pgoff(map, pgoff);
map__set_reloc(map, 0);
map__set_dso(map, dso__get(dso));
map__set_map_ip(map, map__dso_map_ip);
map__set_unmap_ip(map, map__dso_unmap_ip);
map__set_erange_warned(map, false);
refcount_set(map__refcnt(map), 1);
}
@ -317,7 +317,7 @@ void map__fixup_start(struct map *map)
if (nd != NULL) {
struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
map->start = sym->start;
map__set_start(map, sym->start);
}
}
@ -329,7 +329,7 @@ void map__fixup_end(struct map *map)
if (nd != NULL) {
struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
map->end = sym->end;
map__set_end(map, sym->end);
}
}

View File

@ -62,6 +62,16 @@ static inline u64 map__unmap_ip(const struct map *map, u64 ip)
return map->unmap_ip(map, ip);
}
static inline void *map__map_ip_ptr(struct map *map)
{
return map->map_ip;
}
static inline void* map__unmap_ip_ptr(struct map *map)
{
return map->unmap_ip;
}
static inline u64 map__start(const struct map *map)
{
return map->start;
@ -102,6 +112,11 @@ static inline refcount_t *map__refcnt(struct map *map)
return &map->refcnt;
}
static inline bool map__erange_warned(struct map *map)
{
return map->erange_warned;
}
static inline size_t map__size(const struct map *map)
{
return map__end(map) - map__start(map);
@ -231,4 +246,54 @@ static inline int is_no_dso_memory(const char *filename)
!strncmp(filename, "/SYSV", 5) ||
!strcmp(filename, "[heap]");
}
static inline void map__set_start(struct map *map, u64 start)
{
map->start = start;
}
static inline void map__set_end(struct map *map, u64 end)
{
map->end = end;
}
static inline void map__set_pgoff(struct map *map, u64 pgoff)
{
map->pgoff = pgoff;
}
static inline void map__add_pgoff(struct map *map, u64 inc)
{
map->pgoff += inc;
}
static inline void map__set_reloc(struct map *map, u64 reloc)
{
map->reloc = reloc;
}
static inline void map__set_priv(struct map *map, int priv)
{
map->priv = priv;
}
static inline void map__set_erange_warned(struct map *map, bool erange_warned)
{
map->erange_warned = erange_warned;
}
static inline void map__set_dso(struct map *map, struct dso *dso)
{
map->dso = dso;
}
static inline void map__set_map_ip(struct map *map, u64 (*map_ip)(const struct map *map, u64 ip))
{
map->map_ip = map_ip;
}
static inline void map__set_unmap_ip(struct map *map, u64 (*unmap_ip)(const struct map *map, u64 rip))
{
map->unmap_ip = unmap_ip;
}
#endif /* __PERF_MAP_H */

View File

@ -339,7 +339,7 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
goto put_map;
}
before->end = map__start(map);
map__set_end(before, map__start(map));
err = __maps__insert(maps, before);
if (err) {
map__put(before);
@ -359,8 +359,8 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
goto put_map;
}
after->start = map__end(map);
after->pgoff += map__end(map) - map__start(pos->map);
map__set_start(after, map__end(map));
map__add_pgoff(after, map__end(map) - map__start(pos->map));
assert(map__map_ip(pos->map, map__end(map)) ==
map__map_ip(after, map__end(map)));
err = __maps__insert(maps, after);

View File

@ -1354,11 +1354,11 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
*/
if (*remap_kernel && dso->kernel && !kmodule) {
*remap_kernel = false;
map->start = shdr->sh_addr + ref_reloc(kmap);
map->end = map__start(map) + shdr->sh_size;
map->pgoff = shdr->sh_offset;
map->map_ip = map__dso_map_ip;
map->unmap_ip = map__dso_unmap_ip;
map__set_start(map, shdr->sh_addr + ref_reloc(kmap));
map__set_end(map, map__start(map) + shdr->sh_size);
map__set_pgoff(map, shdr->sh_offset);
map__set_map_ip(map, map__dso_map_ip);
map__set_unmap_ip(map, map__dso_unmap_ip);
/* Ensure maps are correctly ordered */
if (kmaps) {
int err;
@ -1379,7 +1379,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
*/
if (*remap_kernel && kmodule) {
*remap_kernel = false;
map->pgoff = shdr->sh_offset;
map__set_pgoff(map, shdr->sh_offset);
}
*curr_mapp = map;
@ -1414,11 +1414,12 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
map__kmap(curr_map)->kmaps = kmaps;
if (adjust_kernel_syms) {
curr_map->start = shdr->sh_addr + ref_reloc(kmap);
curr_map->end = map__start(curr_map) + shdr->sh_size;
curr_map->pgoff = shdr->sh_offset;
map__set_start(curr_map, shdr->sh_addr + ref_reloc(kmap));
map__set_end(curr_map, map__start(curr_map) + shdr->sh_size);
map__set_pgoff(curr_map, shdr->sh_offset);
} else {
curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
map__set_map_ip(curr_map, identity__map_ip);
map__set_unmap_ip(curr_map, identity__map_ip);
}
curr_dso->symtab_type = dso->symtab_type;
if (maps__insert(kmaps, curr_map))
@ -1525,8 +1526,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
if (strcmp(elf_name, kmap->ref_reloc_sym->name))
continue;
kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
map->reloc = kmap->ref_reloc_sym->addr -
kmap->ref_reloc_sym->unrelocated_addr;
map__set_reloc(map, kmap->ref_reloc_sym->addr - kmap->ref_reloc_sym->unrelocated_addr);
break;
}
}
@ -1536,7 +1536,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
* attempted to prelink vdso to its virtual address.
*/
if (dso__is_vdso(dso))
map->reloc = map__start(map) - dso->text_offset;
map__set_reloc(map, map__start(map) - dso->text_offset);
dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap);
/*

View File

@ -279,7 +279,7 @@ void maps__fixup_end(struct maps *maps)
maps__for_each_entry(maps, curr) {
if (prev != NULL && !map__end(prev->map))
prev->map->end = map__start(curr->map);
map__set_end(prev->map, map__start(curr->map));
prev = curr;
}
@ -289,7 +289,7 @@ void maps__fixup_end(struct maps *maps)
* last map final address.
*/
if (curr && !map__end(curr->map))
curr->map->end = ~0ULL;
map__set_end(curr->map, ~0ULL);
up_write(maps__lock(maps));
}
@ -944,7 +944,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
return -1;
}
curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
map__set_map_ip(curr_map, identity__map_ip);
map__set_unmap_ip(curr_map, identity__map_ip);
if (maps__insert(kmaps, curr_map)) {
dso__put(ndso);
return -1;
@ -1250,8 +1251,8 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
return -ENOMEM;
}
list_node->map->end = map__start(list_node->map) + len;
list_node->map->pgoff = pgoff;
map__set_end(list_node->map, map__start(list_node->map) + len);
map__set_pgoff(list_node->map, pgoff);
list_add(&list_node->node, &md->maps);
@ -1286,7 +1287,7 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map)
* |new......| -> |new..|
* |old....| -> |old....|
*/
new_map->end = map__start(old_map);
map__set_end(new_map, map__start(old_map));
} else {
/*
* |new.............| -> |new..| |new..|
@ -1306,10 +1307,10 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map)
goto out;
}
m->map->end = map__start(old_map);
map__set_end(m->map, map__start(old_map));
list_add_tail(&m->node, &merged);
new_map->pgoff += map__end(old_map) - map__start(new_map);
new_map->start = map__end(old_map);
map__add_pgoff(new_map, map__end(old_map) - map__start(new_map));
map__set_start(new_map, map__end(old_map));
}
} else {
/*
@ -1329,8 +1330,8 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map)
* |new......| -> |new...|
* |old....| -> |old....|
*/
new_map->pgoff += map__end(old_map) - map__start(new_map);
new_map->start = map__end(old_map);
map__add_pgoff(new_map, map__end(old_map) - map__start(new_map));
map__set_start(new_map, map__end(old_map));
}
}
}
@ -1457,11 +1458,11 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
list_del_init(&new_node->node);
if (new_map == replacement_map) {
map->start = map__start(new_map);
map->end = map__end(new_map);
map->pgoff = map__pgoff(new_map);
map->map_ip = new_map->map_ip;
map->unmap_ip = new_map->unmap_ip;
map__set_start(map, map__start(new_map));
map__set_end(map, map__end(new_map));
map__set_pgoff(map, map__pgoff(new_map));
map__set_map_ip(map, map__map_ip_ptr(new_map));
map__set_unmap_ip(map, map__unmap_ip_ptr(new_map));
/* Ensure maps are correctly ordered */
map__get(map);
maps__remove(kmaps, map);