BPF List
 help / color / mirror / Atom feed
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.

...

      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