From: Eduard Zingerman <eddyz87@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>, bpf@vger.kernel.org
Cc: daniel@iogearbox.net, andrii@kernel.org, memxor@gmail.com
Subject: Re: [PATCH bpf-next v3 00/45] bpf: A verifier that joins states
Date: Fri, 06 Nov 2026 11:08:14 -0700 [thread overview]
Message-ID: <6d9ffb229ca293c765fd550fb1e0ec988c26adb3.camel@gmail.com> (raw)
In-Reply-To: <20261106035111.3315285-1-alexei.starovoitov@gmail.com>
On Fri, 2026-11-06 at 03:50 +0000, Alexei Starovoitov wrote:
> From: Alexei Starovoitov <ast@kernel.org>
>
> The verifier follows each path of a prog, and each branch can double the
> number of paths. The work grows with the paths, not with the prog:
> insns processed today this series
> rust-bpf scx_beerland/beerland_init_task 1000001 * 17893
> rust-bpf scx_qmap/qmap_init_cids 131088 * 196
> scx scx_eevdf/eevdf_dispatch 350041 15199
> Cilium bpf_host/cil_to_netdev, Oct 2026 64658 7472
> * "BPF program is too large", "The sequence of 8193 jumps is too complex"
>
> Authors cut their progs until they fit. Nobody can cut core, alloc and the
> crates of Rust: of the 653 progs of https://github.com/4ast/rust-bpf 187
> load today, 170 hit one of these limits, 164 get "infinite loop detected"
> and 122 "recursive call". Now 648 load, and no corpus of C progs loses one.
> For rust-bpf both kernels have 4 kfuncs on top, see Numbers.
>
> The idea
> ========
> Do not follow paths. Where paths meet, join their states: r1=1 and r1=5
> give r1=[1,5]. Repeat until no state changes. States stay apart only if
> they have no join, or if a later check depends on the difference.
> loops counted by scalar evolution: one state covers all iterations
> walked: a state per iteration, while constants decide an exit
> all other loops: join at the head, widen, add may_goto
> subprogs A static subprog is verified for the states at its entry, not
> for each chain of calls. Recursion is the same, with widening.
> run time may_goto limits the time of loops and of recursion. r10 limits
> the depth: it must be in the upper half of its kernel stack.
>
> What users see
> ==============
> - The limits of 1M processed insns and 8192 jumps are gone. The limits are
> on states, for a prog of N insns: 1024 at an insn, 16 * N + 4096 at
> a time, 256 * N + 64K in all.
> - "infinite loop detected" is gone: the verifier adds may_goto. A loop
> that has no exit gets "loop at insn N never exits".
> - may_goto is also added to 5 progs of the table below that load today:
> loop1, loop2, loop5, tcp_autolowat_enqueue_rcvq (GCC), chaos_enqueue.
> - Recursion is allowed on x86-64 and arm64. Patch 22 lists the exceptions.
> - All added may_goto of an invocation share its time slice of 250 ms. Then
> the prog returns 0. A subprog that cannot unwind, or a frame that holds
> a lock or a reference, leaves the loop. The stderr stream has the cause.
> - A join loses the relation between scalars. This is rejected now:
> if (c) { i = 3; n = 4; } else { i = 7; n = 8; }
> x = arr[n - i]; n - i is [-3, 5]
> - A cgroup_skb prog whose r0 can be 2 or 3 attaches to egress only. That
> holds for a range too: 'return 1' and 'return 2' are joined to [1, 2].
> - The log has no "mark_precise:", "N: safe", "depth=" and no scc column.
> Level 2 shows "from 13 to 9: within", "joined" or "widened" where states
> meet. The statistics line keeps its format: "limit 0", "mark_read 0".
> - BPF_F_TEST_STATE_FREQ is accepted and has no effect.
>
> Numbers
> =======
> A: bpf-next 8424858a5de0. B: this series, the same objects. The selftests
> that the series adds or changes are not counted. None of them is lost.
>
> Corpus Progs Lost Gained Insns States Mem Time
> --------------------- ----- ---- ------ ----- ------ ---- ----
> selftests 3043 0 1 -63% +120% -18% -27%
> selftests, no_alu32 2905 0 1 -66% +86% -27% -34%
> selftests, cpuv4 2914 0 1 -64% +96% -27% -32%
> selftests, bpf_gcc 2733 0 5 -69% +96% -16% -24%
> 37 builds of Cilium 5189 0 0 -75% +11% -6% -31%
> sched-ext/scx 495 0 0 -89% -34% -66% -67%
> scx, as BPF CI has it 428 0 0 -85% -22% -38% -39%
> tools/sched_ext 240 0 0 -69% +37% +3% -11%
> public progs of Meta 511 0 0 -85% -35% -55% -48%
> all 18458 0 8 -74% +10% -19% -36%
>
> Progs load in A and in B. The per cent compare sums over these progs:
> 75.1M -> 19.2M processed insns, 61 -> 39 s. Mem is mem_peak of veristat.
> Time is the best of 3 runs on kernels without debug options. B counts each
> state that arrives at a basic block as a state, A only those that it saves.
> Gained: loop3 in the 4 builds, 4 progs that A rejects only in GCC's code.
> Of the progs that take 1000 insns or more in B, two take over 5% more than
> in A. loop5, 82 -> 4182: a walk up to its limit of 4096 insns, then a join.
> res_spin_lock_test_held_lock_max, 2356 -> 4088: states that hold different
> numbers of locks have no join.
>
> rust-bpf Progs load in A load in B B: insns time
> 16 schedulers 225 52 225 1.6M 1.9 s
> crates 428 135 423 7.3M 9.4 s
> For rust-bpf A and B have the kfuncs of patches 30-31 of [1] on top. They
> are in no series now. No released compiler emits the code of rust-bpf.
>
> How to read the series
> ======================
> Start with patch 7, the overview. Then 4-5, 13-14, 15, 17 and 19.
> 1-2 what is added to a prog: may_goto, the checks of recursion
> 3-5 union and widening of a range, join.c: the join of two states
> 6-10 data structures of flow.c, passes ahead of the main pass: order of
> the insns, places for may_goto, what later checks depend on
> 11-14 the sets of states, iterations, what is not joined, the merge
> 15-18 how states move: edges, calls and exits, loops, added edges
> 19 the switch. The check of one insn against one state is the same.
> 20-22 more counted loops, static subprogs on their own, recursion
> 23-26 removal of pruning, precision tracking and SCCs: 3382 lines
> 27-28 callx: a pointer to one of a set of functions, live registers
> 29-38 code that needs more than that: casts, the context in a struct,
> subprogs that check for their caller, loops that are not counted
> 39-45 selftests: 39-40 adjust tests, 41-45 add tests
> Each patch builds. Patches 1-18 add the code that patch 19 switches to.
> Some selftests fail from patch 19 to 39.
Hi Alexei,
regarding the Meta veristat failures. Please find distilled examples here:
https://github.com/eddyz87/bpf/tree/ast-new-verifier-v3-meta-tests
Applied as commits on top of your series.
All slop but seem to add up.
...
prev parent reply other threads:[~2026-11-06 18:08 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 3:50 [PATCH bpf-next v3 00/45] bpf: A verifier that joins states Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 01/45] bpf: Add may_goto to the loops that the verifier marks Alexei Starovoitov
2026-11-06 4:22 ` sashiko-bot
2026-11-06 4:38 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 02/45] bpf: Limit depth and time of recursive subprogs at run time Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 03/45] bpf: Add union and widening of the range of a register Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 04/45] bpf: Add join of registers and stack slots Alexei Starovoitov
2026-11-06 4:39 ` sashiko-bot
2026-11-06 3:50 ` [PATCH bpf-next v3 05/45] bpf: Add join of verifier states Alexei Starovoitov
2026-11-06 4:25 ` sashiko-bot
2026-11-06 4:38 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 06/45] bpf: Tell which arguments of a call a join must leave alone Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 07/45] bpf: Add the data structures of the main pass over the control flow graph Alexei Starovoitov
2026-11-06 4:24 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 08/45] bpf: Order the insns, find what stops a loop and where may_goto can go Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 09/45] bpf: Find the registers that hold a number or a pointer to arena Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 10/45] bpf: Find the registers and stack slots that later checks depend on Alexei Starovoitov
2026-11-06 4:08 ` sashiko-bot
2026-11-06 3:50 ` [PATCH bpf-next v3 11/45] bpf: Add the sets of states at an insn and the entries of functions Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 12/45] bpf: Compare states of different iterations of a loop Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 13/45] bpf: Decide which states are not joined Alexei Starovoitov
2026-11-06 4:38 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 14/45] bpf: Merge the state that arrives into the set at an insn Alexei Starovoitov
2026-11-06 4:24 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 15/45] bpf: Move states along edges, into loops and subprogs and out of them Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 16/45] bpf: Make the state after a call from the caller's state and an exit state Alexei Starovoitov
2026-11-06 4:34 ` sashiko-bot
2026-11-06 3:50 ` [PATCH bpf-next v3 17/45] bpf: Enter and leave loops in the main pass, build flow.c Alexei Starovoitov
2026-11-06 4:38 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 18/45] bpf: Tell the passes over the graph where an added may_goto goes Alexei Starovoitov
2026-11-06 4:26 ` sashiko-bot
2026-11-06 3:50 ` [PATCH bpf-next v3 19/45] bpf: Verify programs as a fixpoint over the control flow graph Alexei Starovoitov
2026-11-06 4:38 ` bot+bpf-ci
2026-11-06 4:55 ` sashiko-bot
2026-11-06 3:50 ` [PATCH bpf-next v3 20/45] bpf: Keep the count of a loop when a register has no closed form Alexei Starovoitov
2026-11-06 4:38 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 21/45] bpf: Verify static subprogs on their own Alexei Starovoitov
2026-11-06 4:50 ` bot+bpf-ci
2026-11-06 4:53 ` sashiko-bot
2026-11-06 3:50 ` [PATCH bpf-next v3 22/45] bpf: Allow recursive subprogs Alexei Starovoitov
2026-11-06 4:38 ` bot+bpf-ci
2026-11-06 5:09 ` sashiko-bot
2026-11-06 3:50 ` [PATCH bpf-next v3 23/45] bpf: Remove is_state_visited(), bpf_compute_scc() and iter.depth Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 24/45] bpf: Remove precision tracking Alexei Starovoitov
2026-11-06 4:24 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 25/45] bpf: Remove prune points, levels of state comparison and pop_stack() Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 26/45] bpf: Update comments about paths, pruning and explored states Alexei Starovoitov
2026-11-06 4:19 ` sashiko-bot
2026-11-06 4:24 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 27/45] bpf: Track a pointer to one of a set of functions Alexei Starovoitov
2026-11-06 4:49 ` sashiko-bot
2026-11-06 3:50 ` [PATCH bpf-next v3 28/45] bpf: callx reads what the subprogs whose address is taken read Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 29/45] bpf: Don't take what bpf_core_cast() returns for a number Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 30/45] bpf: Don't widen away a register that only the loop sets Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 31/45] bpf: A base that nothing is known about can be the context Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 32/45] bpf: Keep the frames of the caller for a subprog that loads data_end Alexei Starovoitov
2026-11-06 4:24 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 33/45] bpf: Keep the frames of the caller for ctx of struct_ops with a reference Alexei Starovoitov
2026-11-06 4:24 ` bot+bpf-ci
2026-11-06 3:50 ` [PATCH bpf-next v3 34/45] bpf: R0 is live at the exit that an added may_goto goes to Alexei Starovoitov
2026-11-06 3:50 ` [PATCH bpf-next v3 35/45] bpf: Keep the step of a number in the union of two ranges Alexei Starovoitov
2026-11-06 3:51 ` [PATCH bpf-next v3 36/45] bpf: Keep the first iteration of a counted loop apart Alexei Starovoitov
2026-11-06 4:38 ` bot+bpf-ci
2026-11-06 3:51 ` [PATCH bpf-next v3 37/45] bpf: What a call returns in each iteration is like what the loop loads Alexei Starovoitov
2026-11-06 3:51 ` [PATCH bpf-next v3 38/45] bpf: Find where the jumps of a loop stop a number Alexei Starovoitov
2026-11-06 3:51 ` [PATCH bpf-next v3 39/45] selftests/bpf: Adjust tests to log lines that are gone Alexei Starovoitov
2026-11-06 4:38 ` bot+bpf-ci
2026-11-06 3:51 ` [PATCH bpf-next v3 40/45] selftests/bpf: Adjust tests to new verdicts, messages and order Alexei Starovoitov
2026-11-06 4:25 ` bot+bpf-ci
2026-11-06 4:34 ` sashiko-bot
2026-11-06 3:51 ` [PATCH bpf-next v3 41/45] selftests/bpf: Test states that are not joined Alexei Starovoitov
2026-11-06 3:51 ` [PATCH bpf-next v3 42/45] selftests/bpf: Test static subprogs that are verified on their own Alexei Starovoitov
2026-11-06 3:51 ` [PATCH bpf-next v3 43/45] selftests/bpf: Test loops that are counted, walked or widened Alexei Starovoitov
2026-11-06 3:51 ` [PATCH bpf-next v3 44/45] selftests/bpf: Test progs that run out of budget Alexei Starovoitov
2026-11-06 3:51 ` [PATCH bpf-next v3 45/45] selftests/bpf: Test callx of one of a set of functions Alexei Starovoitov
2026-11-06 4:52 ` sashiko-bot
2026-11-06 18:08 ` Eduard Zingerman [this message]
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=6d9ffb229ca293c765fd550fb1e0ec988c26adb3.camel@gmail.com \
--to=eddyz87@gmail.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=memxor@gmail.com \
/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