From: Ian Rogers <irogers@google.com>
To: irogers@google.com, acme@kernel.org, adrian.hunter@intel.com,
mingo@redhat.com, namhyung@kernel.org, peterz@infradead.org
Cc: ak@linux.intel.com, alexander.shishkin@linux.intel.com,
atrajeev@linux.ibm.com, dvyukov@google.com, fzczx123@gmail.com,
james.clark@linaro.org, jolsa@kernel.org, kjain@linux.ibm.com,
krzysztof.m.lopatowski@gmail.com, leo.yan@arm.com,
lihuafei1@huawei.com, linux-kernel@vger.kernel.org,
linux-perf-users@vger.kernel.org, linux@treblig.org,
m.liska@foxlink.cz, mark.rutland@arm.com, martin.liska@hey.com,
mpetlan@redhat.com, quic_zhonhan@quicinc.com,
scclevenger@os.amperecomputing.com, sesse@google.com,
stephen.s.brennan@oracle.com, thomas.falcon@intel.com,
yangyicong@hisilicon.com
Subject: [PATCH v2 4/8] perf: Refactor thread map and symbol APIs to take perf_sample
Date: Fri, 2 Oct 2026 10:38:37 -0700 [thread overview]
Message-ID: <20261002173848.3228217-5-irogers@google.com> (raw)
In-Reply-To: <20261002173848.3228217-1-irogers@google.com>
Refactor thread__find_map and thread__find_symbol family of APIs to
take a struct perf_sample * instead of cpumode and addr. This prepares
for looking up symbols using build ID and offset, which is contained in
the sample payload instead of the address.
Signed-off-by: Ian Rogers <irogers@google.com>
---
.../arch/powerpc/util/skip-callchain-idx.c | 4 +-
tools/perf/builtin-inject.c | 2 +-
tools/perf/builtin-script.c | 40 +++++++++++----
tools/perf/builtin-timechart.c | 5 +-
tools/perf/builtin-trace.c | 10 ++--
tools/perf/tests/code-reading.c | 4 +-
tools/perf/tests/mmap-thread-lookup.c | 9 +++-
tools/perf/util/annotate-data.c | 5 +-
tools/perf/util/aslr.c | 16 ++++--
tools/perf/util/build-id.c | 2 +-
tools/perf/util/capstone.c | 4 +-
tools/perf/util/cs-etm.c | 4 +-
tools/perf/util/data-convert-json.c | 4 +-
tools/perf/util/debug.c | 4 +-
tools/perf/util/dlfilter.c | 8 ++-
tools/perf/util/event.c | 51 ++++++++++---------
tools/perf/util/intel-pt.c | 14 +++--
tools/perf/util/machine.c | 18 +++++--
tools/perf/util/python.c | 18 +++++--
tools/perf/util/thread.c | 11 ++--
tools/perf/util/thread.h | 14 ++---
tools/perf/util/unwind-libdw.c | 7 ++-
tools/perf/util/unwind-libunwind.c | 8 ++-
23 files changed, 179 insertions(+), 83 deletions(-)
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
index 472714cfad38..cb29d9eafa89 100644
--- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c
+++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
@@ -225,7 +225,9 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain)
addr_location__init(&al);
ip = chain->ips[1];
- thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
+ thread__find_symbol(thread,
+ &(struct perf_sample){.cpumode = PERF_RECORD_MISC_USER, .ip = ip},
+ &al);
if (al.map)
dso = map__dso(al.map);
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 67f019acb6c0..42ed367d729f 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -1167,7 +1167,7 @@ static int perf_event__inject_buildid(const struct perf_tool *tool, union perf_e
goto repipe;
}
- if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) {
+ if (thread__find_map(thread, sample, &al)) {
mark_dso_hit(inject, tool, sample, machine, args.mmap_evsel, al.map,
/*sample_in_dso=*/true);
}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index b6691ebb1b4e..99e9e0c60f14 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1063,6 +1063,7 @@ static int perf_sample__fprintf_brstack(struct perf_sample *sample,
{
struct branch_stack *br = sample->branch_stack;
struct branch_entry *entries = perf_sample__branch_entries(sample);
+ struct perf_sample br_sample = {};
u64 i, from, to;
int printed = 0;
@@ -1079,8 +1080,12 @@ static int perf_sample__fprintf_brstack(struct perf_sample *sample,
addr_location__init(&alf);
addr_location__init(&alt);
- thread__find_map_fb(thread, sample->cpumode, from, &alf);
- thread__find_map_fb(thread, sample->cpumode, to, &alt);
+ br_sample.cpumode = sample->cpumode;
+ br_sample.ip = from;
+ thread__find_map_fb(thread, &br_sample, &alf);
+ br_sample.cpumode = sample->cpumode;
+ br_sample.ip = to;
+ thread__find_map_fb(thread, &br_sample, &alt);
printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
printed += fprintf(fp, "/0x%"PRIx64, to);
@@ -1102,6 +1107,7 @@ static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
{
struct branch_stack *br = sample->branch_stack;
struct branch_entry *entries = perf_sample__branch_entries(sample);
+ struct perf_sample br_sample = {};
u64 i, from, to;
int printed = 0;
@@ -1116,8 +1122,12 @@ static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
from = entries[i].from;
to = entries[i].to;
- thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
- thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
+ br_sample.cpumode = sample->cpumode;
+ br_sample.ip = from;
+ thread__find_symbol_fb(thread, &br_sample, &alf);
+ br_sample.cpumode = sample->cpumode;
+ br_sample.ip = to;
+ thread__find_symbol_fb(thread, &br_sample, &alt);
printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
if (PRINT_FIELD(DSO))
@@ -1140,6 +1150,7 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
{
struct branch_stack *br = sample->branch_stack;
struct branch_entry *entries = perf_sample__branch_entries(sample);
+ struct perf_sample br_sample = {};
u64 i, from, to;
int printed = 0;
@@ -1154,11 +1165,15 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
from = entries[i].from;
to = entries[i].to;
- if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
+ br_sample.cpumode = sample->cpumode;
+ br_sample.ip = from;
+ if (thread__find_map_fb(thread, &br_sample, &alf) &&
!dso__adjust_symbols(map__dso(alf.map)))
from = map__dso_map_ip(alf.map, from);
- if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
+ br_sample.cpumode = sample->cpumode;
+ br_sample.ip = to;
+ if (thread__find_map_fb(thread, &br_sample, &alt) &&
!dso__adjust_symbols(map__dso(alt.map)))
to = map__dso_map_ip(alt.map, to);
@@ -1216,7 +1231,10 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
}
addr_location__init(&al);
- if (!thread__find_map(thread, *cpumode, start, &al) || (dso = map__dso(al.map)) == NULL) {
+ if (!thread__find_map(thread,
+ &(struct perf_sample){.cpumode = *cpumode,
+ .ip = start}, &al) ||
+ (dso = map__dso(al.map)) == NULL) {
pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
goto out;
}
@@ -1291,7 +1309,7 @@ static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)
int ret = 0;
addr_location__init(&al);
- thread__find_map(thread, cpumode, addr, &al);
+ thread__find_map(thread, &(struct perf_sample){.cpumode = cpumode, .ip = addr}, &al);
if (!al.map)
goto out;
ret = map__fprintf_srccode(al.map, al.addr, stdout,
@@ -1346,7 +1364,9 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
struct addr_location al;
addr_location__init(&al);
- thread__find_map(thread, x->cpumode, ip, &al);
+ thread__find_map(thread,
+ &(struct perf_sample){.cpumode = x->cpumode,
+ .ip = ip}, &al);
printed += map__fprintf_srcline(al.map, al.addr, " srcline: ", fp);
printed += fprintf(fp, "\t");
addr_location__exit(&al);
@@ -1406,7 +1426,7 @@ static int ip__fprintf_sym(uint64_t addr, struct thread *thread,
int off, printed = 0, ret = 0;
addr_location__init(&al);
- thread__find_map(thread, cpumode, addr, &al);
+ thread__find_map(thread, &(struct perf_sample){.cpumode = cpumode, .ip = addr}, &al);
if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
goto out;
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 3d88c90c6573..745fd04e478a 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -512,6 +512,7 @@ static char *cat_backtrace(struct perf_sample *sample,
size_t p_len;
u8 cpumode = PERF_RECORD_MISC_USER;
struct ip_callchain *chain = sample->callchain;
+ struct perf_sample ip_sample = {};
FILE *f = open_memstream(&p, &p_len);
bool corrupted = false;
@@ -560,7 +561,9 @@ static char *cat_backtrace(struct perf_sample *sample,
addr_location__init(&tal);
tal.filtered = 0;
- if (thread__find_symbol(al.thread, cpumode, ip, &tal))
+ ip_sample.cpumode = cpumode;
+ ip_sample.ip = ip;
+ if (thread__find_symbol(al.thread, &ip_sample, &tal))
fprintf(f, "..... %016" PRIx64 " %s\n", ip, tal.sym->name);
else
fprintf(f, "..... %016" PRIx64 "\n", ip);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d327603ae454..15b73580c5c2 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -3700,7 +3700,7 @@ static int trace__pgfault(struct trace *trace,
if (trace->summary_only)
goto out;
- thread__find_symbol(thread, sample->cpumode, sample->ip, &al);
+ thread__find_symbol(thread, sample, &al);
trace__fprintf_entry_head(trace, thread, 0, true, sample->time,
sample->cpu, trace->output);
@@ -3713,10 +3713,14 @@ static int trace__pgfault(struct trace *trace,
fprintf(trace->output, "] => ");
- thread__find_symbol(thread, sample->cpumode, sample->addr, &al);
+ thread__find_symbol(thread,
+ &(struct perf_sample){.cpumode = sample->cpumode,
+ .ip = sample->addr}, &al);
if (!al.map) {
- thread__find_symbol(thread, sample->cpumode, sample->addr, &al);
+ thread__find_symbol(thread,
+ &(struct perf_sample){.cpumode = sample->cpumode,
+ .ip = sample->addr}, &al);
if (al.map)
map_type = 'x';
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index c50b526f44fb..f339e2157dfc 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -394,7 +394,9 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
addr_location__init(&al);
- if (!thread__find_map(thread, cpumode, addr, &al) || !map__dso(al.map)) {
+ if (!thread__find_map(thread,
+ &(struct perf_sample){.cpumode = cpumode,
+ .ip = addr}, &al) || !map__dso(al.map)) {
if (cpumode == PERF_RECORD_MISC_HYPERVISOR) {
pr_debug("Hypervisor address can not be resolved - skipping\n");
goto out;
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c
index 0c5619c6e6e9..dca8bbfe780a 100644
--- a/tools/perf/tests/mmap-thread-lookup.c
+++ b/tools/perf/tests/mmap-thread-lookup.c
@@ -195,8 +195,10 @@ static int mmap_events(synth_cb synth)
pr_debug("looking for map %p\n", td->map);
- thread__find_map(thread, PERF_RECORD_MISC_USER,
- (unsigned long) (td->map + 1), &al);
+ thread__find_map(thread, &(struct perf_sample){
+ .cpumode = PERF_RECORD_MISC_USER,
+ .ip = (unsigned long) (td->map + 1),
+ }, &al);
thread__put(thread);
@@ -208,7 +210,10 @@ static int mmap_events(synth_cb synth)
}
pr_debug("map %p, addr %" PRIx64 "\n", al.map, map__start(al.map));
+
addr_location__exit(&al);
+ if (err)
+ break;
}
machine__delete(machine);
diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index 19a6ecd67f28..b53dcb11bbb0 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
@@ -848,8 +848,9 @@ bool get_global_var_info(struct data_loc_info *dloc, u64 addr,
mem_addr = addr + map__reloc(dloc->ms->map);
addr_location__init(&al);
- sym = thread__find_symbol_fb(dloc->thread, dloc->cpumode,
- mem_addr, &al);
+ sym = thread__find_symbol_fb(dloc->thread,
+ &(struct perf_sample){.cpumode = dloc->cpumode,
+ .ip = mem_addr}, &al);
if (sym) {
*var_name = sym->name;
/* Calculate type offset from the start of variable */
diff --git a/tools/perf/util/aslr.c b/tools/perf/util/aslr.c
index e365f807b021..acda28a6fd2d 100644
--- a/tools/perf/util/aslr.c
+++ b/tools/perf/util/aslr.c
@@ -155,7 +155,9 @@ static u64 aslr_tool__remap_address(struct aslr_tool *aslr,
return 0; /* No thread. */
addr_location__init(&al);
- if (!thread__find_map(aslr_thread, cpumode, addr, &al)) {
+ if (!thread__find_map(aslr_thread,
+ &(struct perf_sample){.cpumode = cpumode, .ip = addr},
+ &al)) {
/*
* If lookup fails with specified cpumode, try fallback to the other space
* to be robust against bad cpumode in samples.
@@ -169,7 +171,9 @@ static u64 aslr_tool__remap_address(struct aslr_tool *aslr,
else if (cpumode == PERF_RECORD_MISC_GUEST_USER)
effective_cpumode = PERF_RECORD_MISC_GUEST_KERNEL;
- if (!thread__find_map(aslr_thread, effective_cpumode, addr, &al)) {
+ if (!thread__find_map(aslr_thread,
+ &(struct perf_sample){.cpumode = effective_cpumode,
+ .ip = addr}, &al)) {
addr_location__exit(&al);
return 0; /* No mmap. */
}
@@ -286,7 +290,9 @@ static u64 aslr_tool__findnew_mapping(struct aslr_tool *aslr,
remap_key.pid = (cpumode == PERF_RECORD_MISC_KERNEL ||
cpumode == PERF_RECORD_MISC_GUEST_KERNEL) ?
kernel_pid : thread__pid(aslr_thread);
- if (thread__find_map(aslr_thread, cpumode, start, &al)) {
+ if (thread__find_map(aslr_thread,
+ &(struct perf_sample){.cpumode = cpumode, .ip = start},
+ &al)) {
struct dso *dso = map__dso(al.map);
const char *dso_name = dso ? dso__long_name(dso) : NULL;
@@ -343,7 +349,9 @@ static u64 aslr_tool__findnew_mapping(struct aslr_tool *aslr,
remap_addr = top->remapped_max;
addr_location__init(&prev_al);
- if (thread__find_map(aslr_thread, cpumode, start - 1, &prev_al)) {
+ if (thread__find_map(aslr_thread,
+ &(struct perf_sample){.cpumode = cpumode,
+ .ip = start - 1}, &prev_al)) {
if (map__end(prev_al.map) == start)
is_contiguous = true;
}
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 02233ef0eaff..6c0d33b1609d 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -69,7 +69,7 @@ int build_id__mark_dso_hit(const struct perf_tool *tool __maybe_unused,
}
addr_location__init(&al);
- if (thread__find_map(thread, sample->cpumode, sample->ip, &al))
+ if (thread__find_map(thread, sample, &al))
dso__set_hit(map__dso(al.map));
addr_location__exit(&al);
diff --git a/tools/perf/util/capstone.c b/tools/perf/util/capstone.c
index 95881f15324a..fbad96e1e6a9 100644
--- a/tools/perf/util/capstone.c
+++ b/tools/perf/util/capstone.c
@@ -252,7 +252,9 @@ static size_t print_insn_x86(struct thread *thread, u8 cpumode, struct cs_insn *
addr_location__init(&al);
if (op->type == X86_OP_IMM &&
- thread__find_symbol(thread, cpumode, op->imm, &al)) {
+ thread__find_symbol(thread,
+ &(struct perf_sample){.cpumode = cpumode,
+ .ip = op->imm}, &al)) {
printed += fprintf(fp, "%s ", insn[0].mnemonic);
printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
if (print_opts & PRINT_INSN_IMM_HEX)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 2d1ab34f7b6b..31a11b802c1e 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -1152,7 +1152,9 @@ static u32 __cs_etm__mem_access(struct cs_etm_queue *etmq,
cpumode = cs_etm__cpu_mode(etmq, address, el);
- if (!thread__find_map(thread, cpumode, address, &al))
+ if (!thread__find_map(thread,
+ &(struct perf_sample){.cpumode = cpumode,
+ .ip = address}, &al))
goto out;
dso = map__dso(al.map);
diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-convert-json.c
index 40888b7c4467..8fa7bfdaadff 100644
--- a/tools/perf/util/data-convert-json.c
+++ b/tools/perf/util/data-convert-json.c
@@ -235,7 +235,9 @@ static int process_sample_event(const struct perf_tool *tool,
fputc(',', out);
addr_location__init(&tal);
- ok = thread__find_symbol(al.thread, cpumode, ip, &tal);
+ ok = thread__find_symbol(al.thread,
+ &(struct perf_sample){.cpumode = cpumode,
+ .ip = ip}, &tal);
output_sample_callchain_entry(tool, ip, ok ? &tal : NULL);
addr_location__exit(&tal);
}
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index b7095519419e..2f31b3663ec1 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -339,7 +339,9 @@ void __dump_stack(FILE *file, void **stackdump, size_t stackdump_size)
bool printed = false;
addr_location__init(&al);
- if (thread && thread__find_map(thread, PERF_RECORD_MISC_USER, addr, &al)) {
+ if (thread && thread__find_map(thread,
+ &(struct perf_sample){.cpumode = PERF_RECORD_MISC_USER,
+ .ip = addr}, &al)) {
al.sym = map__find_symbol(al.map, al.addr);
if (al.sym) {
fprintf(file, " #%zd %p in %s ", i, stackdump[i], al.sym->name);
diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c
index e11e144af62b..8a33bfe50939 100644
--- a/tools/perf/util/dlfilter.c
+++ b/tools/perf/util/dlfilter.c
@@ -177,7 +177,9 @@ static __s32 dlfilter__resolve_address(void *ctx, __u64 address, struct perf_dlf
return -1;
addr_location__init(&al);
- thread__find_symbol_fb(thread, d->sample->cpumode, address, &al);
+ thread__find_symbol_fb(thread,
+ &(struct perf_sample){.cpumode = d->sample->cpumode,
+ .ip = address}, &al);
al_to_d_al(&al, &d_al);
@@ -314,7 +316,9 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip, void *buf, __u32 len)
addr_location__init(&a);
- thread__find_map_fb(al->thread, d->sample->cpumode, ip, &a);
+ thread__find_map_fb(al->thread,
+ &(struct perf_sample){.cpumode = d->sample->cpumode,
+ .ip = ip}, &a);
ret = a.map ? code_read(ip, a.map, d->machine, buf, len) : -1;
addr_location__exit(&a);
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index c69ae57ce679..cd13a0c3cb52 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -691,7 +691,7 @@ int perf_event__process(const struct perf_tool *tool __maybe_unused,
return machine__process_event(machine, event, sample);
}
-struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
+struct map *thread__find_map(struct thread *thread, struct perf_sample *sample,
struct addr_location *al)
{
struct maps *maps = thread__maps(thread);
@@ -702,34 +702,34 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
thread__zput(al->thread);
al->thread = thread__get(thread);
- al->addr = addr;
- al->cpumode = cpumode;
+ al->addr = sample->ip;
+ al->cpumode = sample->cpumode;
al->filtered = 0;
if (machine == NULL)
return NULL;
- if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
+ if (sample->cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
al->level = 'k';
maps = machine__kernel_maps(machine);
load_map = !symbol_conf.lazy_load_kernel_maps;
- } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
+ } else if (sample->cpumode == PERF_RECORD_MISC_USER && perf_host) {
al->level = '.';
- } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
+ } else if (sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
al->level = 'g';
maps = machine__kernel_maps(machine);
load_map = !symbol_conf.lazy_load_kernel_maps;
- } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) {
+ } else if (sample->cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) {
al->level = 'u';
} else {
al->level = 'H';
- if ((cpumode == PERF_RECORD_MISC_GUEST_USER ||
- cpumode == PERF_RECORD_MISC_GUEST_KERNEL) &&
+ if ((sample->cpumode == PERF_RECORD_MISC_GUEST_USER ||
+ sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL) &&
!perf_guest)
al->filtered |= (1 << HIST_FILTER__GUEST);
- if ((cpumode == PERF_RECORD_MISC_USER ||
- cpumode == PERF_RECORD_MISC_KERNEL) &&
+ if ((sample->cpumode == PERF_RECORD_MISC_USER ||
+ sample->cpumode == PERF_RECORD_MISC_KERNEL) &&
!perf_host)
al->filtered |= (1 << HIST_FILTER__HOST);
@@ -754,33 +754,34 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
* because it applies only to the sample 'ip' and not necessary to 'addr' or
* branch stack addresses. If possible, use a fallback to deal with those cases.
*/
-struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+struct map *thread__find_map_fb(struct thread *thread, struct perf_sample *sample,
struct addr_location *al)
{
- struct map *map = thread__find_map(thread, cpumode, addr, al);
+ struct map *map = thread__find_map(thread, sample, al);
struct machine *machine = maps__machine(thread__maps(thread));
- u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);
+ u8 addr_cpumode = machine__addr_cpumode(machine, sample->cpumode, sample->ip);
- if (map || addr_cpumode == cpumode)
+ if (map || addr_cpumode == sample->cpumode)
return map;
- return thread__find_map(thread, addr_cpumode, addr, al);
+ sample->cpumode = addr_cpumode;
+ return thread__find_map(thread, sample, al);
}
-struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
- u64 addr, struct addr_location *al)
+struct symbol *thread__find_symbol(struct thread *thread, struct perf_sample *sample,
+ struct addr_location *al)
{
al->sym = NULL;
- if (thread__find_map(thread, cpumode, addr, al))
+ if (thread__find_map(thread, sample, al))
al->sym = map__find_symbol(al->map, al->addr);
return al->sym;
}
-struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
- u64 addr, struct addr_location *al)
+struct symbol *thread__find_symbol_fb(struct thread *thread, struct perf_sample *sample,
+ struct addr_location *al)
{
al->sym = NULL;
- if (thread__find_map_fb(thread, cpumode, addr, al))
+ if (thread__find_map_fb(thread, sample, al))
al->sym = map__find_symbol(al->map, al->addr);
return al->sym;
}
@@ -816,7 +817,7 @@ int machine__resolve(struct machine *machine, struct addr_location *al,
return -1;
dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread__tid(thread));
- thread__find_map(thread, sample->cpumode, sample->ip, al);
+ thread__find_map(thread, sample, al);
dso = al->map ? map__dso(al->map) : NULL;
dump_printf(" ...... dso: %s\n",
dso
@@ -934,7 +935,9 @@ bool sample_addr_correlates_sym(struct perf_event_attr *attr)
void thread__resolve(struct thread *thread, struct addr_location *al,
struct perf_sample *sample)
{
- thread__find_map_fb(thread, sample->cpumode, sample->addr, al);
+ thread__find_map_fb(thread,
+ &(struct perf_sample){.cpumode = sample->cpumode,
+ .ip = sample->addr}, al);
al->cpu = sample->cpu;
al->sym = NULL;
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 8c21c9f52d57..243c252276ad 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -752,6 +752,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
{
struct intel_pt_queue *ptq = data;
struct machine *machine = ptq->pt->machine;
+ struct perf_sample sample = {};
struct thread *thread;
struct addr_location al;
unsigned char buf[INTEL_PT_INSN_BUF_SZ];
@@ -809,10 +810,13 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
}
}
+ sample.cpumode = cpumode;
+
while (1) {
struct dso *dso;
- if (!thread__find_map(thread, cpumode, *ip, &al) || !map__dso(al.map)) {
+ sample.ip = *ip;
+ if (!thread__find_map(thread, &sample, &al) || !map__dso(al.map)) {
if (al.map)
intel_pt_log("ERROR: thread has no dso for %#" PRIx64 "\n", *ip);
else
@@ -1007,7 +1011,9 @@ static int __intel_pt_pgd_ip(uint64_t ip, void *data)
return -EINVAL;
addr_location__init(&al);
- if (!thread__find_map(thread, cpumode, ip, &al) || !map__dso(al.map))
+ if (!thread__find_map(thread,
+ &(struct perf_sample){.cpumode = cpumode,
+ .ip = ip}, &al) || !map__dso(al.map))
return -EINVAL;
offset = map__map_ip(al.map, ip);
@@ -3656,7 +3662,9 @@ static int intel_pt_find_map(struct thread *thread, u8 cpumode, u64 addr,
struct addr_location *al)
{
if (!al->map || addr < map__start(al->map) || addr >= map__end(al->map)) {
- if (!thread__find_map(thread, cpumode, addr, al))
+ if (!thread__find_map(thread,
+ &(struct perf_sample){.cpumode = cpumode,
+ .ip = addr}, al))
return -1;
}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 4bcb16da6481..1a13253d0c7f 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2064,6 +2064,7 @@ static void ip__resolve_ams(struct thread *thread,
struct addr_map_symbol *ams,
u64 ip)
{
+ static __thread struct perf_sample sample;
struct addr_location al;
addr_location__init(&al);
@@ -2074,7 +2075,8 @@ static void ip__resolve_ams(struct thread *thread,
* Thus, we have to try consecutively until we find a match
* or else, the symbol is unknown
*/
- thread__find_cpumode_addr_location(thread, ip, /*symbols=*/true, &al);
+ sample.ip = ip;
+ thread__find_cpumode_addr_location(thread, &sample, /*symbols=*/true, &al);
ams->addr = ip;
ams->al_addr = al.addr;
@@ -2091,11 +2093,14 @@ static void ip__resolve_data(struct thread *thread,
u8 m, struct addr_map_symbol *ams,
u64 addr, u64 phys_addr, u64 daddr_page_size)
{
+ static __thread struct perf_sample sample;
struct addr_location al;
addr_location__init(&al);
- thread__find_symbol(thread, m, addr, &al);
+ sample.cpumode = m;
+ sample.ip = addr;
+ thread__find_symbol(thread, &sample, &al);
ams->addr = addr;
ams->al_addr = al.addr;
@@ -2218,6 +2223,7 @@ static int add_callchain_ip(struct thread *thread,
u64 branch_from,
bool symbols)
{
+ static __thread struct perf_sample sample;
struct map_symbol ms = {};
struct addr_location al;
int nr_loop_iter = 0, err = 0;
@@ -2228,8 +2234,9 @@ static int add_callchain_ip(struct thread *thread,
al.filtered = 0;
al.sym = NULL;
al.srcline = NULL;
+ sample.ip = ip;
if (!cpumode) {
- thread__find_cpumode_addr_location(thread, ip, symbols, &al);
+ thread__find_cpumode_addr_location(thread, &sample, symbols, &al);
} else {
if (ip >= PERF_CONTEXT_MAX) {
switch (ip) {
@@ -2256,10 +2263,11 @@ static int add_callchain_ip(struct thread *thread,
}
goto out;
}
+ sample.cpumode = *cpumode;
if (symbols)
- thread__find_symbol(thread, *cpumode, ip, &al);
+ thread__find_symbol(thread, &sample, &al);
else
- thread__find_map(thread, *cpumode, ip, &al);
+ thread__find_map(thread, &sample, &al);
}
if (al.sym != NULL) {
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index cc9257e2cceb..a1f156fadc44 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -851,7 +851,10 @@ static PyObject *pyrf_sample_event__srccode(PyObject *self, PyObject *args)
if (addr != pevent->sample.ip) {
addr_location__init(&al);
- thread__find_symbol_fb(pevent->al.thread, pevent->sample.cpumode, addr, &al);
+ thread__find_symbol_fb(pevent->al.thread,
+ &(struct perf_sample){
+ .cpumode = pevent->sample.cpumode,
+ .ip = addr}, &al);
} else {
addr_location__init(&al);
al.thread = thread__get(pevent->al.thread);
@@ -1242,8 +1245,12 @@ static int pyrf_sample_event__resolve_addr_al(struct pyrf_event *pevent,
if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.thread)
return -1;
- thread__find_symbol_fb(pevent->al.thread, pevent->sample.cpumode,
- pevent->sample.addr, addr_al);
+ thread__find_symbol_fb(pevent->al.thread,
+ &(struct perf_sample){
+ .cpumode = pevent->sample.cpumode,
+ .ip = pevent->sample.addr,
+ },
+ addr_al);
return 0;
}
@@ -4363,6 +4370,7 @@ static PyObject *pyrf_call_path__to_callchain(const struct call_path *cp,
struct thread *thread)
{
struct pyrf_callchain *pchain;
+ struct perf_sample sample = {};
const struct call_path *pos;
u64 nr_frames = 0;
@@ -4395,7 +4403,9 @@ static PyObject *pyrf_call_path__to_callchain(const struct call_path *cp,
: PERF_RECORD_MISC_USER;
addr_location__init(&al);
- thread__find_map(thread, cpumode, pos->ip, &al);
+ sample.cpumode = cpumode;
+ sample.ip = pos->ip;
+ thread__find_map(thread, &sample, &al);
frame->map = map__get(al.map);
if (frame->map)
frame->sym = pos->sym;
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 91118c301913..ad3f1ae8a92e 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -413,7 +413,7 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bo
return thread__clone_maps(thread, parent, do_maps_clone);
}
-void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
+void thread__find_cpumode_addr_location(struct thread *thread, struct perf_sample *sample,
bool symbols, struct addr_location *al)
{
size_t i;
@@ -425,10 +425,11 @@ void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
};
for (i = 0; i < ARRAY_SIZE(cpumodes); i++) {
+ sample->cpumode = cpumodes[i];
if (symbols)
- thread__find_symbol(thread, cpumodes[i], addr, al);
+ thread__find_symbol(thread, sample, al);
else
- thread__find_map(thread, cpumodes[i], addr, al);
+ thread__find_map(thread, sample, al);
if (al->map)
break;
@@ -579,6 +580,7 @@ int thread__memcpy(struct thread *thread, struct machine *machine,
void *buf, u64 ip, int len, bool *is64bit)
{
u8 cpumode = PERF_RECORD_MISC_USER;
+ struct perf_sample sample = { .ip = ip };
struct addr_location al;
struct dso *dso;
long offset;
@@ -587,7 +589,8 @@ int thread__memcpy(struct thread *thread, struct machine *machine,
cpumode = PERF_RECORD_MISC_KERNEL;
addr_location__init(&al);
- if (!thread__find_map(thread, cpumode, ip, &al)) {
+ sample.cpumode = cpumode;
+ if (!thread__find_map(thread, &sample, &al)) {
addr_location__exit(&al);
return -1;
}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index d82fce8173ae..f0c50eafeee5 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -124,17 +124,17 @@ size_t thread__fprintf(struct thread *thread, FILE *fp);
struct thread *thread__main_thread(struct machine *machine, struct thread *thread);
-struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
+struct map *thread__find_map(struct thread *thread, struct perf_sample *sample,
struct addr_location *al);
-struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+struct map *thread__find_map_fb(struct thread *thread, struct perf_sample *sample,
struct addr_location *al);
-struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
- u64 addr, struct addr_location *al);
-struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
- u64 addr, struct addr_location *al);
+struct symbol *thread__find_symbol(struct thread *thread, struct perf_sample *sample,
+ struct addr_location *al);
+struct symbol *thread__find_symbol_fb(struct thread *thread, struct perf_sample *sample,
+ struct addr_location *al);
-void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
+void thread__find_cpumode_addr_location(struct thread *thread, struct perf_sample *sample,
bool symbols, struct addr_location *al);
int thread__memcpy(struct thread *thread, struct machine *machine,
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index d49901b1571e..855faa54c0cf 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -82,7 +82,9 @@ static int __report_module(struct addr_location *al, u64 ip,
* Some callers will use al->sym, so we can't just use the
* cheaper thread__find_map() here.
*/
- thread__find_symbol(ui->thread, PERF_RECORD_MISC_USER, ip, al);
+ thread__find_symbol(ui->thread,
+ &(struct perf_sample){.cpumode = PERF_RECORD_MISC_USER, .ip = ip},
+ al);
if (al->map)
dso = map__dso(al->map);
@@ -208,13 +210,14 @@ static bool get_thread(Dwfl *dwfl __maybe_unused, pid_t tid, void *arg,
static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr,
Dwarf_Word *data, size_t len)
{
+ struct perf_sample sample = { .cpumode = PERF_RECORD_MISC_USER, .ip = addr };
struct addr_location al;
union u64_swap u;
ssize_t size;
struct dso *dso;
addr_location__init(&al);
- if (!thread__find_map(ui->thread, PERF_RECORD_MISC_USER, addr, &al)) {
+ if (!thread__find_map(ui->thread, &sample, &al)) {
pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
goto out_fail;
}
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 6052383e862b..83f043f266da 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -370,7 +370,9 @@ static struct map *find_map(uint64_t ip, struct unwind_info *ui)
struct map *ret;
addr_location__init(&al);
- thread__find_map(ui->thread, PERF_RECORD_MISC_USER, ip, &al);
+ thread__find_map(ui->thread,
+ &(struct perf_sample){.cpumode = PERF_RECORD_MISC_USER, .ip = ip},
+ &al);
ret = map__get(al.map);
addr_location__exit(&al);
return ret;
@@ -626,7 +628,9 @@ static int entry(uint64_t ip, struct thread *thread, unwind_entry_cb_t cb, void
int ret;
addr_location__init(&al);
- e.ms.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
+ e.ms.sym = thread__find_symbol(thread,
+ &(struct perf_sample){.cpumode = PERF_RECORD_MISC_USER,
+ .ip = ip}, &al);
e.ip = ip;
e.ms.map = al.map;
e.ms.thread = thread__get(al.thread);
--
2.56.0.rc1.315.gc6ed9934b7-goog
next prev parent reply other threads:[~2026-10-02 17:39 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-24 6:19 [PATCH v1 0/5] perf: Default use of build IDs and improvements Ian Rogers
2025-04-24 6:19 ` [PATCH v1 1/5] perf build-id: Reduce size of "size" variable Ian Rogers
2025-04-24 6:19 ` [PATCH v1 2/5] perf build-id: Truncate to avoid overflowing the build_id data Ian Rogers
2025-04-24 6:19 ` [PATCH v1 3/5] perf build-id: Change sprintf functions to snprintf Ian Rogers
2025-04-24 6:19 ` [PATCH v1 4/5] perf dso: Move build_id to dso_id Ian Rogers
2025-04-24 6:19 ` [PATCH v1 5/5] perf record: Make --buildid-mmap the default Ian Rogers
2025-04-24 7:20 ` Ian Rogers
2025-04-25 14:45 ` Arnaldo Carvalho de Melo
2025-04-25 14:59 ` Arnaldo Carvalho de Melo
2025-04-25 16:03 ` Ian Rogers
2026-10-02 17:38 ` [PATCH v2 0/8] perf/core, perf/tools: Add PERF_SAMPLE_BUILD_ID_OFFSET support Ian Rogers
2026-10-02 17:38 ` [PATCH v2 1/8] perf event: Factor build_id out into its own top-level struct Ian Rogers
2026-10-03 1:33 ` sashiko-bot
2026-10-02 17:38 ` [PATCH v2 2/8] perf/core: Add BUILD_ID_OFFSET to UAPI Ian Rogers
2026-10-03 1:33 ` sashiko-bot
2026-10-02 17:38 ` [PATCH v2 3/8] perf/core: Implement BUILD_ID_OFFSET sample type Ian Rogers
2026-10-03 1:33 ` sashiko-bot
2026-10-02 17:38 ` Ian Rogers [this message]
2026-10-03 1:33 ` [PATCH v2 4/8] perf: Refactor thread map and symbol APIs to take perf_sample sashiko-bot
2026-10-02 17:38 ` [PATCH v2 5/8] perf tools: Internal support for BUILD_ID_OFFSET Ian Rogers
2026-10-03 1:33 ` sashiko-bot
2026-10-02 17:38 ` [PATCH v2 6/8] perf inject: Extend perf inject to support bid_offset conversion Ian Rogers
2026-10-03 1:33 ` sashiko-bot
2026-10-02 17:38 ` [PATCH v2 7/8] perf record: Add --buildid-offset option Ian Rogers
2026-10-03 1:33 ` sashiko-bot
2026-10-02 17:38 ` [PATCH v2 8/8] perf tests: Add build_id_offset test coverage Ian Rogers
2026-10-03 1:33 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261002173848.3228217-5-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=atrajeev@linux.ibm.com \
--cc=dvyukov@google.com \
--cc=fzczx123@gmail.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=kjain@linux.ibm.com \
--cc=krzysztof.m.lopatowski@gmail.com \
--cc=leo.yan@arm.com \
--cc=lihuafei1@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux@treblig.org \
--cc=m.liska@foxlink.cz \
--cc=mark.rutland@arm.com \
--cc=martin.liska@hey.com \
--cc=mingo@redhat.com \
--cc=mpetlan@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=quic_zhonhan@quicinc.com \
--cc=scclevenger@os.amperecomputing.com \
--cc=sesse@google.com \
--cc=stephen.s.brennan@oracle.com \
--cc=thomas.falcon@intel.com \
--cc=yangyicong@hisilicon.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.