perf callchain: Don't pass evsel and sample

As struct perf_sample now directly contains its own resolved evsel pointer,
passing the evsel separately is redundant and clutters the interface.

Remove the redundant evsel parameter from callchain-specific handlers and
structures, ensuring the tool always directly accesses the evsel bound to the
sample. This simplifies the API signatures and eliminates the risk of passing
an inconsistent evsel.

Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Andrew Jones <ajones@ventanamicro.com>
Cc: Anup Patel <anup@brainfault.org>
Cc: Athira Rajeev <atrajeev@linux.ibm.com>
Cc: Blake Jones <blakejones@google.com>
Cc: Chen Ni <nichen@iscas.ac.cn>
Cc: Chun-Tse Shao <ctshao@google.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Derek Foreman <derek.foreman@collabora.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Dr. David Alan Gilbert <linux@treblig.org>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Hrishikesh Suresh <hrishikesh123s@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Krzysztof Łopatowski <krzysztof.m.lopatowski@gmail.com>
Cc: Leo Yan <leo.yan@arm.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Quan Zhou <zhouquan@iscas.ac.cn>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Swapnil Sapkal <swapnil.sapkal@amd.com>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Cc: Tianyou Li <tianyou.li@intel.com>
Cc: Yujie Liu <yujie.liu@intel.com>
Cc: tanze <tanze@kylinos.cn>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Ian Rogers 2026-05-20 12:05:11 -07:00 committed by Arnaldo Carvalho de Melo
parent a50a9b0d6e
commit 859e495970
17 changed files with 48 additions and 57 deletions

View File

@ -339,7 +339,7 @@ static int process_sample_event(const struct perf_tool *tool __maybe_unused,
cursor = get_tls_callchain_cursor();
ret = sample__resolve_callchain(sample, cursor, NULL,
evsel, &al, sysctl_perf_event_max_stack);
&al, sysctl_perf_event_max_stack);
if (ret)
goto out;

View File

@ -521,7 +521,7 @@ static int perf_event__convert_sample_callchain(const struct perf_tool *tool,
goto out;
/* this will parse DWARF using stack and register data */
ret = thread__resolve_callchain(thread, cursor, evsel, sample,
ret = thread__resolve_callchain(thread, cursor, sample,
/*parent=*/NULL, /*root_al=*/NULL,
PERF_MAX_STACK_DEPTH);
thread__put(thread);
@ -1130,7 +1130,7 @@ static int perf_event__inject_buildid(const struct perf_tool *tool, union perf_e
/*sample_in_dso=*/true);
}
sample__for_each_callchain_node(thread, sample->evsel, sample, PERF_MAX_STACK_DEPTH,
sample__for_each_callchain_node(thread, sample, PERF_MAX_STACK_DEPTH,
/*symbols=*/false, mark_dso_hit_callback, &args);
thread__put(thread);
repipe:

View File

@ -394,7 +394,7 @@ static int build_alloc_func_list(void)
* Find first non-memory allocation function from callchain.
* The allocation functions are in the 'alloc_func_list'.
*/
static u64 find_callsite(struct evsel *evsel, struct perf_sample *sample)
static u64 find_callsite(struct perf_sample *sample)
{
struct addr_location al;
struct machine *machine = &kmem_session->machines.host;
@ -414,7 +414,7 @@ static u64 find_callsite(struct evsel *evsel, struct perf_sample *sample)
if (cursor == NULL)
goto out;
sample__resolve_callchain(sample, cursor, NULL, evsel, &al, 16);
sample__resolve_callchain(sample, cursor, /*parent=*/NULL, &al, 16);
callchain_cursor_commit(cursor);
while (true) {
@ -838,7 +838,7 @@ static int evsel__process_page_alloc_event(struct evsel *evsel, struct perf_samp
if (parse_gfp_flags(evsel, sample, gfp_flags) < 0)
return -1;
callsite = find_callsite(evsel, sample);
callsite = find_callsite(sample);
/*
* This is to find the current page (with correct gfp flags and

View File

@ -688,7 +688,6 @@ static int latency_entry_event(struct perf_kwork *kwork,
static void timehist_save_callchain(struct perf_kwork *kwork,
struct perf_sample *sample,
struct evsel *evsel,
struct machine *machine)
{
struct symbol *sym;
@ -708,7 +707,7 @@ static void timehist_save_callchain(struct perf_kwork *kwork,
cursor = get_tls_callchain_cursor();
if (thread__resolve_callchain(thread, cursor, evsel, sample,
if (thread__resolve_callchain(thread, cursor, sample,
NULL, NULL, kwork->max_stack + 2) != 0) {
pr_debug("Failed to resolve callchain, skipping\n");
goto out_put;
@ -838,7 +837,7 @@ static int timehist_entry_event(struct perf_kwork *kwork,
return ret;
if (work != NULL)
timehist_save_callchain(kwork, sample, evsel, machine);
timehist_save_callchain(kwork, sample, machine);
return 0;
}

View File

@ -551,13 +551,13 @@ static int get_key_by_aggr_mode_simple(u64 *key, u64 addr, u32 tid)
return 0;
}
static u64 callchain_id(struct evsel *evsel, struct perf_sample *sample);
static u64 callchain_id(struct perf_sample *sample);
static int get_key_by_aggr_mode(u64 *key, u64 addr, struct evsel *evsel,
static int get_key_by_aggr_mode(u64 *key, u64 addr,
struct perf_sample *sample)
{
if (aggr_mode == LOCK_AGGR_CALLER) {
*key = callchain_id(evsel, sample);
*key = callchain_id(sample);
return 0;
}
return get_key_by_aggr_mode_simple(key, addr, sample->tid);
@ -841,7 +841,7 @@ static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip,
else
return strlcpy(buf, sym->name, size);
}
static int lock_contention_caller(struct evsel *evsel, struct perf_sample *sample,
static int lock_contention_caller(struct perf_sample *sample,
char *buf, int size)
{
struct thread *thread;
@ -862,7 +862,7 @@ static int lock_contention_caller(struct evsel *evsel, struct perf_sample *sampl
cursor = get_tls_callchain_cursor();
/* use caller function name from the callchain */
ret = thread__resolve_callchain(thread, cursor, evsel, sample,
ret = thread__resolve_callchain(thread, cursor, sample,
NULL, NULL, max_stack_depth);
if (ret != 0) {
thread__put(thread);
@ -896,7 +896,7 @@ static int lock_contention_caller(struct evsel *evsel, struct perf_sample *sampl
return -1;
}
static u64 callchain_id(struct evsel *evsel, struct perf_sample *sample)
static u64 callchain_id(struct perf_sample *sample)
{
struct callchain_cursor *cursor;
struct machine *machine = &session->machines.host;
@ -911,7 +911,7 @@ static u64 callchain_id(struct evsel *evsel, struct perf_sample *sample)
cursor = get_tls_callchain_cursor();
/* use caller function name from the callchain */
ret = thread__resolve_callchain(thread, cursor, evsel, sample,
ret = thread__resolve_callchain(thread, cursor, sample,
NULL, NULL, max_stack_depth);
thread__put(thread);
@ -963,7 +963,7 @@ static u64 *get_callstack(struct perf_sample *sample, int max_stack)
return callstack;
}
static int report_lock_contention_begin_event(struct evsel *evsel,
static int report_lock_contention_begin_event(struct evsel *evsel __maybe_unused,
struct perf_sample *sample)
{
struct lock_stat *ls;
@ -978,7 +978,7 @@ static int report_lock_contention_begin_event(struct evsel *evsel,
struct map *kmap;
struct symbol *sym;
ret = get_key_by_aggr_mode(&key, addr, evsel, sample);
ret = get_key_by_aggr_mode(&key, addr, sample);
if (ret < 0)
return ret;
@ -1025,7 +1025,7 @@ static int report_lock_contention_begin_event(struct evsel *evsel,
break;
case LOCK_AGGR_CALLER:
name = buf;
if (lock_contention_caller(evsel, sample, buf, sizeof(buf)) < 0)
if (lock_contention_caller(sample, buf, sizeof(buf)) < 0)
name = "Unknown";
break;
case LOCK_AGGR_CGROUP:
@ -1127,7 +1127,7 @@ static int report_lock_contention_begin_event(struct evsel *evsel,
return 0;
}
static int report_lock_contention_end_event(struct evsel *evsel,
static int report_lock_contention_end_event(struct evsel *evsel __maybe_unused,
struct perf_sample *sample)
{
struct lock_stat *ls;
@ -1138,7 +1138,7 @@ static int report_lock_contention_end_event(struct evsel *evsel,
u64 key;
int ret;
ret = get_key_by_aggr_mode(&key, addr, evsel, sample);
ret = get_key_by_aggr_mode(&key, addr, sample);
if (ret < 0)
return ret;

View File

@ -2325,7 +2325,6 @@ static bool is_idle_sample(struct perf_sample *sample,
static void save_task_callchain(struct perf_sched *sched,
struct perf_sample *sample,
struct evsel *evsel,
struct machine *machine)
{
struct callchain_cursor *cursor;
@ -2345,7 +2344,7 @@ static void save_task_callchain(struct perf_sched *sched,
cursor = get_tls_callchain_cursor();
if (thread__resolve_callchain(thread, cursor, evsel, sample,
if (thread__resolve_callchain(thread, cursor, sample,
NULL, NULL, sched->max_stack + 2) != 0) {
if (verbose > 0)
pr_err("Failed to resolve callchain. Skipping\n");
@ -2519,7 +2518,7 @@ static struct thread *timehist_get_thread(struct perf_sched *sched,
sample->tid);
}
save_task_callchain(sched, sample, evsel, machine);
save_task_callchain(sched, sample, machine);
if (sched->idle_hist) {
struct thread *idle;
struct idle_thread_runtime *itr;

View File

@ -1684,7 +1684,7 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample,
if (symbol_conf.use_callchain && sample->callchain) {
cursor = get_tls_callchain_cursor();
if (thread__resolve_callchain(al->thread, cursor, evsel,
if (thread__resolve_callchain(al->thread, cursor,
sample, NULL, NULL,
scripting_max_stack))
cursor = NULL;
@ -2507,7 +2507,7 @@ static void process_event(struct perf_script *script,
if (symbol_conf.use_callchain && sample->callchain) {
cursor = get_tls_callchain_cursor();
if (thread__resolve_callchain(al->thread, cursor, evsel,
if (thread__resolve_callchain(al->thread, cursor,
sample, NULL, NULL,
scripting_max_stack))
cursor = NULL;
@ -2792,7 +2792,7 @@ static int process_deferred_sample_event(const struct perf_tool *tool,
if (symbol_conf.use_callchain && sample->callchain) {
cursor = get_tls_callchain_cursor();
if (thread__resolve_callchain(al.thread, cursor, evsel,
if (thread__resolve_callchain(al.thread, cursor,
sample, NULL, NULL,
scripting_max_stack)) {
pr_info("cannot resolve deferred callchains\n");

View File

@ -2938,7 +2938,7 @@ static int trace__resolve_callchain(struct trace *trace,
if (machine__resolve(trace->host, &al, sample) < 0)
goto out;
err = thread__resolve_callchain(al.thread, cursor, evsel, sample, NULL, NULL, max_stack);
err = thread__resolve_callchain(al.thread, cursor, sample, NULL, NULL, max_stack);
out:
addr_location__exit(&al);
return err;

View File

@ -73,7 +73,7 @@ int build_id__mark_dso_hit(const struct perf_tool *tool __maybe_unused,
addr_location__exit(&al);
sample__for_each_callchain_node(thread, sample->evsel, sample, PERF_MAX_STACK_DEPTH,
sample__for_each_callchain_node(thread, sample, PERF_MAX_STACK_DEPTH,
/*symbols=*/false, mark_dso_hit_callback, /*data=*/NULL);

View File

@ -1170,7 +1170,7 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
int sample__resolve_callchain(struct perf_sample *sample,
struct callchain_cursor *cursor, struct symbol **parent,
struct evsel *evsel, struct addr_location *al,
struct addr_location *al,
int max_stack)
{
if (sample->callchain == NULL && !symbol_conf.show_branchflag_count)
@ -1178,7 +1178,7 @@ int sample__resolve_callchain(struct perf_sample *sample,
if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain ||
perf_hpp_list.parent || symbol_conf.show_branchflag_count) {
return thread__resolve_callchain(al->thread, cursor, evsel, sample,
return thread__resolve_callchain(al->thread, cursor, sample,
parent, al, max_stack);
}
return 0;
@ -1853,7 +1853,7 @@ s64 callchain_avg_cycles(struct callchain_node *cnode)
return cycles;
}
int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel,
int sample__for_each_callchain_node(struct thread *thread,
struct perf_sample *sample, int max_stack,
bool symbols, callchain_iter_fn cb, void *data)
{
@ -1864,7 +1864,7 @@ int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel,
return -ENOMEM;
/* Fill in the callchain. */
ret = __thread__resolve_callchain(thread, cursor, evsel, sample,
ret = __thread__resolve_callchain(thread, cursor, sample,
/*parent=*/NULL, /*root_al=*/NULL,
max_stack, symbols);
if (ret)

View File

@ -8,11 +8,9 @@
#include "branch.h"
struct addr_location;
struct evsel;
struct hist_entry;
struct hists;
struct ip_callchain;
struct map;
struct perf_sample;
struct record_opts;
struct thread;
@ -245,7 +243,7 @@ int record_opts__parse_callchain(struct record_opts *record,
int sample__resolve_callchain(struct perf_sample *sample,
struct callchain_cursor *cursor, struct symbol **parent,
struct evsel *evsel, struct addr_location *al,
struct addr_location *al,
int max_stack);
int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node,
@ -306,7 +304,7 @@ s64 callchain_avg_cycles(struct callchain_node *cnode);
typedef int (*callchain_iter_fn)(struct callchain_cursor_node *node, void *data);
int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel,
int sample__for_each_callchain_node(struct thread *thread,
struct perf_sample *sample, int max_stack,
bool symbols, callchain_iter_fn cb, void *data);

View File

@ -208,8 +208,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al,
static struct call_path *call_path_from_sample(struct db_export *dbe,
struct machine *machine,
struct thread *thread,
struct perf_sample *sample,
struct evsel *evsel)
struct perf_sample *sample)
{
u64 kernel_start = machine__kernel_start(machine);
struct call_path *current = &dbe->cpr->call_path;
@ -227,7 +226,7 @@ static struct call_path *call_path_from_sample(struct db_export *dbe,
*/
callchain_param.order = ORDER_CALLER;
cursor = get_tls_callchain_cursor();
err = thread__resolve_callchain(thread, cursor, evsel,
err = thread__resolve_callchain(thread, cursor,
sample, NULL, NULL, PERF_MAX_STACK_DEPTH);
if (err) {
callchain_param.order = saved_order;
@ -390,8 +389,7 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
if (dbe->cpr) {
struct call_path *cp = call_path_from_sample(dbe, machine,
thread, sample,
evsel);
thread, sample);
if (cp) {
db_export__call_path(dbe, cp);
es.call_path_id = cp->db_id;

View File

@ -1342,7 +1342,7 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
alm = map__get(al->map);
err = sample__resolve_callchain(iter->sample, get_tls_callchain_cursor(), &iter->parent,
iter->evsel, al, max_stack_depth);
al, max_stack_depth);
if (err) {
map__put(alm);
return err;

View File

@ -2778,13 +2778,13 @@ static u64 get_leaf_frame_caller(struct perf_sample *sample,
static int thread__resolve_callchain_sample(struct thread *thread,
struct callchain_cursor *cursor,
struct evsel *evsel,
struct perf_sample *sample,
struct symbol **parent,
struct addr_location *root_al,
int max_stack,
bool symbols)
{
struct evsel *evsel = sample->evsel;
struct branch_stack *branch = sample->branch_stack;
struct branch_entry *entries = perf_sample__branch_entries(sample);
struct ip_callchain *chain = sample->callchain;
@ -2986,10 +2986,11 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
static int thread__resolve_callchain_unwind(struct thread *thread,
struct callchain_cursor *cursor,
struct evsel *evsel,
struct perf_sample *sample,
int max_stack, bool symbols)
{
struct evsel *evsel = sample->evsel;
/* Can we do dwarf post unwind? */
if (!((evsel->core.attr.sample_type & PERF_SAMPLE_REGS_USER) &&
(evsel->core.attr.sample_type & PERF_SAMPLE_STACK_USER)))
@ -3009,7 +3010,6 @@ static int thread__resolve_callchain_unwind(struct thread *thread,
int __thread__resolve_callchain(struct thread *thread,
struct callchain_cursor *cursor,
struct evsel *evsel,
struct perf_sample *sample,
struct symbol **parent,
struct addr_location *root_al,
@ -3025,22 +3025,22 @@ int __thread__resolve_callchain(struct thread *thread,
if (callchain_param.order == ORDER_CALLEE) {
ret = thread__resolve_callchain_sample(thread, cursor,
evsel, sample,
sample,
parent, root_al,
max_stack, symbols);
if (ret)
return ret;
ret = thread__resolve_callchain_unwind(thread, cursor,
evsel, sample,
sample,
max_stack, symbols);
} else {
ret = thread__resolve_callchain_unwind(thread, cursor,
evsel, sample,
sample,
max_stack, symbols);
if (ret)
return ret;
ret = thread__resolve_callchain_sample(thread, cursor,
evsel, sample,
sample,
parent, root_al,
max_stack, symbols);
}

View File

@ -187,7 +187,6 @@ struct callchain_cursor;
int __thread__resolve_callchain(struct thread *thread,
struct callchain_cursor *cursor,
struct evsel *evsel,
struct perf_sample *sample,
struct symbol **parent,
struct addr_location *root_al,
@ -196,7 +195,6 @@ int __thread__resolve_callchain(struct thread *thread,
static inline int thread__resolve_callchain(struct thread *thread,
struct callchain_cursor *cursor,
struct evsel *evsel,
struct perf_sample *sample,
struct symbol **parent,
struct addr_location *root_al,
@ -204,7 +202,6 @@ static inline int thread__resolve_callchain(struct thread *thread,
{
return __thread__resolve_callchain(thread,
cursor,
evsel,
sample,
parent,
root_al,

View File

@ -257,7 +257,7 @@ static void define_event_symbols(struct tep_event *event,
}
static SV *perl_process_callchain(struct perf_sample *sample,
struct evsel *evsel,
struct evsel *evsel __maybe_unused,
struct addr_location *al)
{
struct callchain_cursor *cursor;
@ -272,7 +272,7 @@ static SV *perl_process_callchain(struct perf_sample *sample,
cursor = get_tls_callchain_cursor();
if (thread__resolve_callchain(al->thread, cursor, evsel,
if (thread__resolve_callchain(al->thread, cursor,
sample, NULL, NULL, scripting_max_stack) != 0) {
pr_err("Failed to resolve callchain. Skipping\n");
goto exit;

View File

@ -390,7 +390,7 @@ static unsigned long get_offset(struct symbol *sym, struct addr_location *al)
}
static PyObject *python_process_callchain(struct perf_sample *sample,
struct evsel *evsel,
struct evsel *evsel __maybe_unused,
struct addr_location *al)
{
PyObject *pylist;
@ -404,7 +404,7 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
goto exit;
cursor = get_tls_callchain_cursor();
if (thread__resolve_callchain(al->thread, cursor, evsel,
if (thread__resolve_callchain(al->thread, cursor,
sample, NULL, NULL,
scripting_max_stack) != 0) {
pr_err("Failed to resolve callchain. Skipping\n");