bpf: Factor callchain_finalize function from __bpf_get_stack

The new callchain_finalize function calls the build-id retrieval
(if needed) and zeroes the buffer. This makes things easier for
preemption fix in following change.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260803210149.296496-8-jolsa@kernel.org
This commit is contained in:
Jiri Olsa
2026-08-03 23:01:44 +02:00
committed by Andrii Nakryiko
parent cbb99938e7
commit 014fbe5902

View File

@@ -764,16 +764,31 @@ static u32 callchain_store(struct perf_callchain_entry *trace, void *buf,
return trace_nr;
}
static long callchain_finalize(void *buf, u32 size, u32 trace_nr, u32 elem_size,
u64 flags, bool may_fault)
{
bool user_build_id = flags & BPF_F_USER_BUILD_ID;
bool user = flags & BPF_F_USER_STACK;
u32 copy_len = trace_nr * elem_size;
if (user_build_id)
stack_map_get_build_id_offset(buf, trace_nr, user, may_fault);
if (size > copy_len)
memset(buf + copy_len, 0, size - copy_len);
return copy_len;
}
static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task,
struct perf_callchain_entry *trace_in,
void *buf, u32 size, u64 flags, bool may_fault)
{
u32 trace_nr, copy_len, elem_size, max_depth;
bool user_build_id = flags & BPF_F_USER_BUILD_ID;
bool crosstask = task && task != current;
u32 skip = flags & BPF_F_SKIP_FIELD_MASK;
bool user = flags & BPF_F_USER_STACK;
struct perf_callchain_entry *trace;
u32 trace_nr, elem_size, max_depth;
bool kernel = !user;
int err = -EINVAL;
@@ -821,18 +836,12 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task,
}
trace_nr = callchain_store(trace, buf, elem_size, flags);
copy_len = trace_nr * elem_size;
/* trace should not be dereferenced after this point */
if (may_fault)
rcu_read_unlock();
if (user_build_id)
stack_map_get_build_id_offset(buf, trace_nr, user, may_fault);
if (size > copy_len)
memset(buf + copy_len, 0, size - copy_len);
return copy_len;
return callchain_finalize(buf, size, trace_nr, elem_size, flags, may_fault);
err_fault:
err = -EFAULT;