From: Yonghong Song <yonghong.song@linux.dev>
To: bot+bpf-ci@kernel.org, bpf@vger.kernel.org
Cc: ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net,
eddyz87@gmail.com, kernel-team@fb.com, martin.lau@kernel.org,
mason@kernel.org, ihor.solodrai@linux.dev
Subject: Re: [PATCH bpf-next v8 05/22] bpf: Prepare for an exception cleanup table before the CFG walk
Date: Fri, 2 Oct 2026 20:06:50 +0100 [thread overview]
Message-ID: <24f7d004-9e71-41ca-abd3-dacf952ede23@linux.dev> (raw)
In-Reply-To: <0660232bb0b94d963dba9a2f9022669c4e97c5e0a94bd7acc674f21f18b036e6@mail.kernel.org>
On 10/1/26 7:31 AM, bot+bpf-ci@kernel.org wrote:
>> bpf: Prepare for an exception cleanup table before the CFG walk
> TL;DR: bpf_exc_check_prog() rescans the whole program for bpf_throw, and a
> later patch calls it at every bpf_unwind() visit, so verification time may
> balloon on large programs; suggests caching the result.
>
>> diff --git a/kernel/bpf/exception.c b/kernel/bpf/exception.c
>> index 3ea1bff5cc90..e12cdb12cde3 100644
>> --- a/kernel/bpf/exception.c
>> +++ b/kernel/bpf/exception.c
>> @@ -141,6 +141,85 @@ int bpf_exc_check_info(struct bpf_verifier_env *env, const union bpf_attr *attr,
> [ ... ]
>
>> +static int reject_throw(struct bpf_verifier_env *env)
>> +{
>> + u32 i;
>> +
>> + for (i = 0; i < env->prog->len; i++) {
>> + if (!bpf_is_throw_kfunc(&env->prog->insnsi[i]))
>> + continue;
>> + verbose(env,
>> + "exception cleanup cannot be combined with bpf_throw at insn %u\n",
>> + i);
>> + return -EINVAL;
>> + }
>> + return 0;
>> +}
> [ ... ]
>
>> +int bpf_exc_check_prog(struct bpf_verifier_env *env)
>> +{
>> + int err;
>> +
> [ ... ]
>
>> + err = reject_throw(env);
>> + if (err)
>> + return err;
>> + env->prog->jit_required = 1;
>> + return 0;
>> +}
> Can this scan make verification time grow with the number of bpf_unwind()
> instructions the verifier visits?
>
> The commit message says the checks in bpf_exc_check_prog() are also run
> "at every bpf_unwind()", and a later patch in the series (5de314709a62
> "bpf: Dispatch cleanup pads by rewriting return addresses") does that from
> process_bpf_unwind():
>
> static int process_bpf_unwind(struct bpf_verifier_env *env, ...)
> {
> ...
> err = bpf_exc_check_prog(env);
>
> Each of those calls reaches reject_throw(), which walks all env->prog->len
> instructions looking for bpf_throw.
>
> None of the things bpf_exc_check_prog() tests can change once do_check()
> is running: the offload flag, jit_requested, exception_callback_subprog and
> whether a bpf_throw insn exists are all fixed before the main pass. Only
> env->ops can change, and only for struct_ops, in check_attach_btf_id()
> before do_check().
>
> So the scan gives the same answer each time, but every visit costs
> O(prog->len) instead of O(1). That means the BPF_COMPLEXITY_LIMIT_INSNS
> budget no longer bounds verifier cost linearly; the cost becomes roughly
> visits * prog_len.
>
> For example, a program with about 500K reachable insns plus a bounded loop
> of the form "if (x == i) bpf_unwind();" could reach bpf_unwind() tens of
> thousands of times within the 1M processed insn budget. Each visit would
> rescan 500K insns, which is around 10^10 to 10^11 extra iterations, or
> tens of seconds of extra verifier CPU for a single load.
>
> Would it make sense to run reject_throw() once and cache the result in
> env? Alternatively, the bpf_unwind() path could re-check only the
> gen_epilogue condition, which is the one that becomes known after
> bpf_exc_prepare().
As you mentioned, yes, this is an optimization issue. We can remove
bpf_exc_check_prog() for checking per bpf_unwind() insn. We can do
a collective checking after all insns are checked. This way
bpf_exc_check_prog() will be called only once.
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/36872142096
next prev parent reply other threads:[~2026-10-02 19:06 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 13:30 [PATCH bpf-next v8 00/22] bpf: Run exception cleanup landing pads when bpf_unwind() unwinds Yonghong Song
2026-10-01 13:30 ` [PATCH bpf-next v8 01/22] bpf: Pack bpf_insn_aux_data flags into bit fields Yonghong Song
2026-10-01 13:30 ` [PATCH bpf-next v8 02/22] bpf: Accept the compiler's exception cleanup table at program load Yonghong Song
2026-10-01 13:30 ` [PATCH bpf-next v8 03/22] bpf: Add the bpf_unwind() and bpf_unwind_resume() kfuncs Yonghong Song
2026-10-01 13:30 ` [PATCH bpf-next v8 04/22] bpf: Add lookups for exception cleanup resumes and landing pads Yonghong Song
2026-10-01 13:48 ` sashiko-bot
2026-10-02 18:17 ` Yonghong Song
2026-10-01 13:30 ` [PATCH bpf-next v8 05/22] bpf: Prepare for an exception cleanup table before the CFG walk Yonghong Song
2026-10-01 14:31 ` bot+bpf-ci
2026-10-02 19:06 ` Yonghong Song [this message]
2026-10-01 13:30 ` [PATCH bpf-next v8 06/22] bpf: Make exception landing pads reachable in the CFG Yonghong Song
2026-10-01 13:30 ` [PATCH bpf-next v8 07/22] bpf: Follow an unwind to its landing pad in the verifier Yonghong Song
2026-10-01 13:50 ` sashiko-bot
2026-10-02 19:31 ` Yonghong Song
2026-10-01 14:31 ` bot+bpf-ci
2026-10-02 20:49 ` Yonghong Song
2026-10-03 12:23 ` Alexei Starovoitov
2026-10-04 17:56 ` Yonghong Song
2026-10-01 13:30 ` [PATCH bpf-next v8 08/22] bpf: Require an unwind to leave a frame holding what it entered with Yonghong Song
2026-10-01 14:31 ` bot+bpf-ci
2026-10-02 21:10 ` Yonghong Song
2026-10-03 12:25 ` Alexei Starovoitov
2026-10-04 17:59 ` Yonghong Song
2026-10-01 13:30 ` [PATCH bpf-next v8 09/22] bpf: Refuse a landing pad that does not resume Yonghong Song
2026-10-03 12:25 ` Alexei Starovoitov
2026-10-04 18:26 ` Yonghong Song
2026-10-01 13:30 ` [PATCH bpf-next v8 10/22] bpf: Do not use a private stack for a program that can unwind Yonghong Song
2026-10-01 13:53 ` sashiko-bot
2026-10-02 21:38 ` Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 11/22] bpf: Dispatch cleanup pads by rewriting return addresses Yonghong Song
2026-10-01 14:31 ` bot+bpf-ci
2026-10-02 21:48 ` Yonghong Song
2026-10-03 12:26 ` Alexei Starovoitov
2026-10-04 18:28 ` Yonghong Song
2026-10-04 18:29 ` Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 12/22] bpf, x86: Dispatch exception cleanup pads at run time Yonghong Song
2026-10-01 13:49 ` sashiko-bot
2026-10-02 21:54 ` Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 13/22] bpf, arm64: " Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 14/22] libbpf: Resolve the compiler's _Unwind_Resume to the kernel's kfunc Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 15/22] libbpf: Add cleanup_info to bpf_prog_load_opts Yonghong Song
2026-10-01 13:46 ` sashiko-bot
2026-10-02 22:09 ` Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 16/22] libbpf: Collect .bpf_cleanup records and pass them to the kernel Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 17/22] libbpf: Carry the exception cleanup table through the light skeleton Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 18/22] libbpf: Let the static linker carry .bpf_cleanup relocations Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 19/22] selftests/bpf: Add end-to-end and negative .bpf_cleanup exception tests Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 20/22] selftests/bpf: Add __set_global() and __ret_global() test tags Yonghong Song
2026-10-01 13:31 ` [PATCH bpf-next v8 21/22] selftests/bpf: Cover more accepted .bpf_cleanup exception shapes Yonghong Song
2026-10-01 13:32 ` [PATCH bpf-next v8 22/22] selftests/bpf: Load an exception cleanup program from a light skeleton Yonghong Song
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=24f7d004-9e71-41ca-abd3-dacf952ede23@linux.dev \
--to=yonghong.song@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bot+bpf-ci@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=kernel-team@fb.com \
--cc=martin.lau@kernel.org \
--cc=mason@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox