From: Jiri Olsa <jolsa@kernel.org> mainline inclusion from mainline-v7.3-rc1 commit 15f1bd8574662f1b7b26aaa2e23ebf4066f0117d category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19054 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- The get_perf_callchain call needs disabled preemption plus we need it disabled as long as we access its returned trace entries buffer. Note the bpf_get_stackid_pe function is executed already with preemption disabled. Fixes: d5a3b1f69186 ("bpf: introduce BPF_MAP_TYPE_STACK_TRACE") Reported-by: Tao Chen <chen.dylane@linux.dev> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/bpf/20260803210149.296496-6-jolsa@kernel.org Closes: https://lore.kernel.org/bpf/20260206090653.1336687-2-chen.dylane@linux.dev/ Conflicts: kernel/bpf/stackmap.c [ctx conflicts] Signed-off-by: Pu Lehui <pulehui@huawei.com> --- kernel/bpf/stackmap.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c index ffb19791f632..12bb2f66f03a 100644 --- a/kernel/bpf/stackmap.c +++ b/kernel/bpf/stackmap.c @@ -368,20 +368,22 @@ BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map, return -EINVAL; max_depth = stack_map_calculate_max_depth(map->value_size, elem_size, flags); - trace = get_perf_callchain(regs, 0, kernel, user, max_depth, - false, false); - if (unlikely(!trace)) - /* couldn't fetch the stack trace */ - return -EFAULT; + scoped_guard(preempt) { + trace = get_perf_callchain(regs, 0, kernel, user, max_depth, + false, false); + if (unlikely(!trace)) + /* couldn't fetch the stack trace */ + return -EFAULT; - err = stackid_fastpath(&stackid, map, trace, flags); - if (err != -ENOENT) - return err; + err = stackid_fastpath(&stackid, map, trace, flags); + if (err != -ENOENT) + return err; - new_bucket = stackid_new_bucket(&stackid, map); - if (!new_bucket) - return -ENOMEM; + new_bucket = stackid_new_bucket(&stackid, map); + if (!new_bucket) + return -ENOMEM; + } return stackid_install(&stackid, map, new_bucket, flags); } -- 2.34.1