diff mbox series

[v2] bpf: make function do_misc_fixups as noinline_for_stack

Message ID 20240711054525.20748-1-flyingpeng@tencent.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series [v2] bpf: make function do_misc_fixups as noinline_for_stack | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
netdev/series_format warning Single patches do not need cover letters; Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 816 this patch: 816
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 16 maintainers not CCed: kpsingh@kernel.org haoluo@google.com nathan@kernel.org john.fastabend@gmail.com song@kernel.org morbo@google.com sdf@fomichev.me daniel@iogearbox.net llvm@lists.linux.dev andrii@kernel.org justinstitt@google.com jolsa@kernel.org yonghong.song@linux.dev martin.lau@linux.dev eddyz87@gmail.com ndesaulniers@google.com
netdev/build_clang success Errors and warnings before: 821 this patch: 821
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 831 this patch: 831
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-7 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-9 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for s390x-gcc / test (test_maps, false, 360) / test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for s390x-gcc / test (test_maps, false, 360) / test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-17 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-31 success Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-32 success Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-42 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-next-VM_Test-21 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-41 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-38 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-29 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-next-VM_Test-40 success Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-26 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-39 success Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-30 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-34 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-next-VM_Test-22 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-33 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-25 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-35 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-20 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-36 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-next-VM_Test-14 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc

Commit Message

Hao Peng July 11, 2024, 5:45 a.m. UTC
From: Peng Hao <flyingpeng@tencent.com>

When KASAN is enabled and built with clang:
kernel/bpf/verifier.c:21486:5: error: stack frame size (2264) exceeds limit (2048) in 'bpf_check' [-Werror,-Wframe-larger-than]
int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
    ^

By tracing the call chain, we found that do_misc_fixups consumed a lot
of stack space. mark it as noinline_for_stack to prevent it from spreading
to bpf_check's stack size.

Signed-off-by: Peng Hao <flyingpeng@tencent.com>
---
 kernel/bpf/verifier.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Alexei Starovoitov July 12, 2024, 4:43 p.m. UTC | #1
On Wed, Jul 10, 2024 at 10:45 PM <flyingpenghao@gmail.com> wrote:
>
>
> By tracing the call chain, we found that do_misc_fixups consumed a lot
> of stack space. mark it as noinline_for_stack to prevent it from spreading
> to bpf_check's stack size.

...
> -static int do_misc_fixups(struct bpf_verifier_env *env)
> +static noinline_for_stack int do_misc_fixups(struct bpf_verifier_env *env)

Now we're getting somewhere, but this is not a fix.
It may shut up the warn, but it will only increase the total stack usage.
Looking at C code do_misc_fixups() needs ~200 bytes worth of stack
space for insn_buf[16] and spill/fill.
That's far from the artificial 2k limit.

Please figure out what exact variable is causing kasan to consume
so much stack. You may need to analyze compiler internals and
do more homework.
What is before/after stack usage ? with and without kasan?
With gcc try
+CFLAGS_verifier.o += -fstack-usage

I see:
sort -k2 -n kernel/bpf/verifier.su |tail -10
../kernel/bpf/verifier.c:13087:12:adjust_ptr_min_max_vals    240
dynamic,bounded
../kernel/bpf/verifier.c:20804:12:do_check_common    248    dynamic,bounded
../kernel/bpf/verifier.c:19151:12:convert_ctx_accesses    256    static
../kernel/bpf/verifier.c:7450:12:check_mem_reg    256    static
../kernel/bpf/verifier.c:7482:12:check_kfunc_mem_size_reg    256    static
../kernel/bpf/verifier.c:10268:12:check_helper_call.isra    272
dynamic,bounded
../kernel/bpf/verifier.c:21562:5:bpf_check    296    dynamic,bounded
../kernel/bpf/verifier.c:19860:12:do_misc_fixups    320    static
../kernel/bpf/verifier.c:13991:12:adjust_reg_min_max_vals    392    static
../kernel/bpf/verifier.c:12280:12:check_kfunc_call.isra    408
dynamic,bounded

do_misc_fixups() is not the smallest, but not that large either.

Do in-depth analysis instead of silencing the warn.

pw-bot: cr
Hao Peng July 25, 2024, 6:18 a.m. UTC | #2
On Sat, Jul 13, 2024 at 12:43 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Wed, Jul 10, 2024 at 10:45 PM <flyingpenghao@gmail.com> wrote:
> >
> >
> > By tracing the call chain, we found that do_misc_fixups consumed a lot
> > of stack space. mark it as noinline_for_stack to prevent it from spreading
> > to bpf_check's stack size.
>
> ...
> > -static int do_misc_fixups(struct bpf_verifier_env *env)
> > +static noinline_for_stack int do_misc_fixups(struct bpf_verifier_env *env)
>
> Now we're getting somewhere, but this is not a fix.
> It may shut up the warn, but it will only increase the total stack usage.
> Looking at C code do_misc_fixups() needs ~200 bytes worth of stack
> space for insn_buf[16] and spill/fill.
> That's far from the artificial 2k limit.
>
> Please figure out what exact variable is causing kasan to consume
> so much stack. You may need to analyze compiler internals and
> do more homework.
> What is before/after stack usage ? with and without kasan?
> With gcc try
> +CFLAGS_verifier.o += -fstack-usage
>
> I see:
> sort -k2 -n kernel/bpf/verifier.su |tail -10
> ../kernel/bpf/verifier.c:13087:12:adjust_ptr_min_max_vals    240
> dynamic,bounded
> ../kernel/bpf/verifier.c:20804:12:do_check_common    248    dynamic,bounded
> ../kernel/bpf/verifier.c:19151:12:convert_ctx_accesses    256    static
> ../kernel/bpf/verifier.c:7450:12:check_mem_reg    256    static
> ../kernel/bpf/verifier.c:7482:12:check_kfunc_mem_size_reg    256    static
> ../kernel/bpf/verifier.c:10268:12:check_helper_call.isra    272
> dynamic,bounded
> ../kernel/bpf/verifier.c:21562:5:bpf_check    296    dynamic,bounded
> ../kernel/bpf/verifier.c:19860:12:do_misc_fixups    320    static
> ../kernel/bpf/verifier.c:13991:12:adjust_reg_min_max_vals    392    static
> ../kernel/bpf/verifier.c:12280:12:check_kfunc_call.isra    408
> dynamic,bounded
>
> do_misc_fixups() is not the smallest, but not that large either.
>
If I use gcc, I get the same result as you, but if I use llvm to build
the kernel, the result is like this:
# sort -k2 -n kernel/bpf/verifier.su | tail -10
kernel/bpf/verifier.c:14026:adjust_reg_min_max_vals     440     static
kernel/bpf/verifier.c:7432:check_mem_reg        440     static
kernel/bpf/verifier.c:15955:check_cfg   472     static
kernel/bpf/verifier.c:7464:check_kfunc_mem_size_reg     472     static
kernel/bpf/verifier.c:15104:check_cond_jmp_op   504     static
kernel/bpf/verifier.c:4166:__mark_chain_precision       504     static
kernel/bpf/verifier.c:10239:check_helper_call   536     static
kernel/bpf/verifier.c:17744:do_check    792     static
kernel/bpf/verifier.c:12248:check_kfunc_call    984     static
kernel/bpf/verifier.c:21486:bpf_check   2456    static

Obviously, do_misc_fixups is automatically inlined into bpf_check.
So adding noinline_for_stack to the do_misc_fixups function is a solution.

Thanks.

> Do in-depth analysis instead of silencing the warn.
>
> pw-bot: cr
Yonghong Song July 25, 2024, 3:34 p.m. UTC | #3
On 7/24/24 11:18 PM, Hao Peng wrote:
> On Sat, Jul 13, 2024 at 12:43 AM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
>> On Wed, Jul 10, 2024 at 10:45 PM <flyingpenghao@gmail.com> wrote:
>>>
>>> By tracing the call chain, we found that do_misc_fixups consumed a lot
>>> of stack space. mark it as noinline_for_stack to prevent it from spreading
>>> to bpf_check's stack size.
>> ...
>>> -static int do_misc_fixups(struct bpf_verifier_env *env)
>>> +static noinline_for_stack int do_misc_fixups(struct bpf_verifier_env *env)
>> Now we're getting somewhere, but this is not a fix.
>> It may shut up the warn, but it will only increase the total stack usage.
>> Looking at C code do_misc_fixups() needs ~200 bytes worth of stack
>> space for insn_buf[16] and spill/fill.
>> That's far from the artificial 2k limit.
>>
>> Please figure out what exact variable is causing kasan to consume
>> so much stack. You may need to analyze compiler internals and
>> do more homework.
>> What is before/after stack usage ? with and without kasan?
>> With gcc try
>> +CFLAGS_verifier.o += -fstack-usage
>>
>> I see:
>> sort -k2 -n kernel/bpf/verifier.su |tail -10
>> ../kernel/bpf/verifier.c:13087:12:adjust_ptr_min_max_vals    240
>> dynamic,bounded
>> ../kernel/bpf/verifier.c:20804:12:do_check_common    248    dynamic,bounded
>> ../kernel/bpf/verifier.c:19151:12:convert_ctx_accesses    256    static
>> ../kernel/bpf/verifier.c:7450:12:check_mem_reg    256    static
>> ../kernel/bpf/verifier.c:7482:12:check_kfunc_mem_size_reg    256    static
>> ../kernel/bpf/verifier.c:10268:12:check_helper_call.isra    272
>> dynamic,bounded
>> ../kernel/bpf/verifier.c:21562:5:bpf_check    296    dynamic,bounded
>> ../kernel/bpf/verifier.c:19860:12:do_misc_fixups    320    static
>> ../kernel/bpf/verifier.c:13991:12:adjust_reg_min_max_vals    392    static
>> ../kernel/bpf/verifier.c:12280:12:check_kfunc_call.isra    408
>> dynamic,bounded
>>
>> do_misc_fixups() is not the smallest, but not that large either.
>>
> If I use gcc, I get the same result as you, but if I use llvm to build
> the kernel, the result is like this:
> # sort -k2 -n kernel/bpf/verifier.su | tail -10
> kernel/bpf/verifier.c:14026:adjust_reg_min_max_vals     440     static
> kernel/bpf/verifier.c:7432:check_mem_reg        440     static
> kernel/bpf/verifier.c:15955:check_cfg   472     static
> kernel/bpf/verifier.c:7464:check_kfunc_mem_size_reg     472     static
> kernel/bpf/verifier.c:15104:check_cond_jmp_op   504     static
> kernel/bpf/verifier.c:4166:__mark_chain_precision       504     static
> kernel/bpf/verifier.c:10239:check_helper_call   536     static
> kernel/bpf/verifier.c:17744:do_check    792     static
> kernel/bpf/verifier.c:12248:check_kfunc_call    984     static
> kernel/bpf/verifier.c:21486:bpf_check   2456    static
>
> Obviously, do_misc_fixups is automatically inlined into bpf_check.
> So adding noinline_for_stack to the do_misc_fixups function is a solution.

Looks like you are building your own kernel with KASAN.
You can change config CONFIG_FRAME_WARN value. In your config file you
have CONFIG_FRAME_WARN=2048. You can change it to
CONFIG_FRAME_WARN=4096 which should fix the issue.

>
> Thanks.
>
>> Do in-depth analysis instead of silencing the warn.
>>
>> pw-bot: cr
diff mbox series

Patch

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 48f3a9acdef3..ba1bf742a33d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -19791,7 +19791,7 @@  static int add_hidden_subprog(struct bpf_verifier_env *env, struct bpf_insn *pat
 /* Do various post-verification rewrites in a single program pass.
  * These rewrites simplify JIT and interpreter implementations.
  */
-static int do_misc_fixups(struct bpf_verifier_env *env)
+static noinline_for_stack int do_misc_fixups(struct bpf_verifier_env *env)
 {
 	struct bpf_prog *prog = env->prog;
 	enum bpf_attach_type eatype = prog->expected_attach_type;