mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 13:23:02 -04:00
bpf: Remove trace_in argument from __bpf_get_stack
Now with the new callchain_* helper functions we can process trace_in case directly in bpf_get_stack_pe function and remove it from __bpf_get_stack which 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-9-jolsa@kernel.org
This commit is contained in:
committed by
Andrii Nakryiko
parent
014fbe5902
commit
58cfc2201d
@@ -780,7 +780,6 @@ static long callchain_finalize(void *buf, u32 size, u32 trace_nr, u32 elem_size,
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
bool user_build_id = flags & BPF_F_USER_BUILD_ID;
|
||||
@@ -819,10 +818,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task,
|
||||
if (may_fault)
|
||||
rcu_read_lock(); /* need RCU for perf's callchain below */
|
||||
|
||||
if (trace_in) {
|
||||
trace = trace_in;
|
||||
trace->nr = min_t(u32, trace->nr, max_depth);
|
||||
} else if (kernel && task) {
|
||||
if (kernel && task) {
|
||||
trace = get_callchain_entry_for_task(task, max_depth);
|
||||
} else {
|
||||
trace = get_perf_callchain(regs, kernel, user, max_depth,
|
||||
@@ -853,7 +849,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task,
|
||||
BPF_CALL_4(bpf_get_stack, struct pt_regs *, regs, void *, buf, u32, size,
|
||||
u64, flags)
|
||||
{
|
||||
return __bpf_get_stack(regs, NULL, NULL, buf, size, flags, false /* !may_fault */);
|
||||
return __bpf_get_stack(regs, NULL, buf, size, flags, false /* !may_fault */);
|
||||
}
|
||||
|
||||
const struct bpf_func_proto bpf_get_stack_proto = {
|
||||
@@ -869,7 +865,7 @@ const struct bpf_func_proto bpf_get_stack_proto = {
|
||||
BPF_CALL_4(bpf_get_stack_sleepable, struct pt_regs *, regs, void *, buf, u32, size,
|
||||
u64, flags)
|
||||
{
|
||||
return __bpf_get_stack(regs, NULL, NULL, buf, size, flags, true /* may_fault */);
|
||||
return __bpf_get_stack(regs, NULL, buf, size, flags, true /* may_fault */);
|
||||
}
|
||||
|
||||
const struct bpf_func_proto bpf_get_stack_sleepable_proto = {
|
||||
@@ -893,7 +889,7 @@ static long __bpf_get_task_stack(struct task_struct *task, void *buf, u32 size,
|
||||
|
||||
regs = task_pt_regs(task);
|
||||
if (regs)
|
||||
res = __bpf_get_stack(regs, task, NULL, buf, size, flags, may_fault);
|
||||
res = __bpf_get_stack(regs, task, buf, size, flags, may_fault);
|
||||
put_task_stack(task);
|
||||
|
||||
return res;
|
||||
@@ -933,6 +929,32 @@ const struct bpf_func_proto bpf_get_task_stack_sleepable_proto = {
|
||||
.arg4_type = ARG_ANYTHING,
|
||||
};
|
||||
|
||||
static int __bpf_get_stack_pe(struct perf_callchain_entry *trace, void *buf, u32 size,
|
||||
u64 flags)
|
||||
{
|
||||
bool user_build_id = flags & BPF_F_USER_BUILD_ID;
|
||||
u64 skip = flags & BPF_F_SKIP_FIELD_MASK;
|
||||
bool user = flags & BPF_F_USER_STACK;
|
||||
u32 elem_size, max_depth, nr_trace;
|
||||
bool kernel = !user;
|
||||
|
||||
if (kernel && user_build_id)
|
||||
return -EINVAL;
|
||||
|
||||
elem_size = user_build_id ? sizeof(struct bpf_stack_build_id) : sizeof(u64);
|
||||
if (unlikely(size % elem_size))
|
||||
return -EINVAL;
|
||||
|
||||
max_depth = stack_map_calculate_max_depth(size, elem_size, flags);
|
||||
trace->nr = min_t(u32, trace->nr, max_depth);
|
||||
|
||||
if (trace->nr < skip)
|
||||
return -EFAULT;
|
||||
|
||||
nr_trace = callchain_store(trace, buf, elem_size, flags);
|
||||
return callchain_finalize(buf, size, nr_trace, elem_size, flags, false /* !may_fault */);
|
||||
}
|
||||
|
||||
BPF_CALL_4(bpf_get_stack_pe, struct bpf_perf_event_data_kern *, ctx,
|
||||
void *, buf, u32, size, u64, flags)
|
||||
{
|
||||
@@ -944,7 +966,7 @@ BPF_CALL_4(bpf_get_stack_pe, struct bpf_perf_event_data_kern *, ctx,
|
||||
__u64 nr_kernel;
|
||||
|
||||
if (!(event->attr.sample_type & PERF_SAMPLE_CALLCHAIN))
|
||||
return __bpf_get_stack(regs, NULL, NULL, buf, size, flags, false /* !may_fault */);
|
||||
return __bpf_get_stack(regs, NULL, buf, size, flags, false /* !may_fault */);
|
||||
|
||||
if (unlikely(flags & ~(BPF_F_SKIP_FIELD_MASK | BPF_F_USER_STACK |
|
||||
BPF_F_USER_BUILD_ID)))
|
||||
@@ -964,7 +986,7 @@ BPF_CALL_4(bpf_get_stack_pe, struct bpf_perf_event_data_kern *, ctx,
|
||||
__u64 nr = trace->nr;
|
||||
|
||||
trace->nr = nr_kernel;
|
||||
err = __bpf_get_stack(regs, NULL, trace, buf, size, flags, false /* !may_fault */);
|
||||
err = __bpf_get_stack_pe(trace, buf, size, flags);
|
||||
|
||||
/* restore nr */
|
||||
trace->nr = nr;
|
||||
@@ -974,14 +996,13 @@ BPF_CALL_4(bpf_get_stack_pe, struct bpf_perf_event_data_kern *, ctx,
|
||||
skip += nr_kernel;
|
||||
if (skip > BPF_F_SKIP_FIELD_MASK)
|
||||
goto clear;
|
||||
|
||||
flags = (flags & ~BPF_F_SKIP_FIELD_MASK) | skip;
|
||||
err = __bpf_get_stack(regs, NULL, trace, buf, size, flags, false /* !may_fault */);
|
||||
err = __bpf_get_stack_pe(trace, buf, size, flags);
|
||||
}
|
||||
return err;
|
||||
|
||||
clear:
|
||||
memset(buf, 0, size);
|
||||
if (err < 0)
|
||||
memset(buf, 0, size);
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user