freenode
Kernel & Low-Level

BPF verifier gains precision, loop counting, and higher limits

Alexei Starovoitov’s 37-patch series lets the verifier accept more compiler output, including Rust and GCC forms that previously failed.

Alexei Starovoitov has posted a 37-patch series for bpf-next that widens what the BPF verifier will accept from real compilers without changing its core path-following model.

The work tightens precision tracking so a packet pointer keeps its known range when a non-negative scalar is added, and so shifts, divisions and remainders by a range produce usable bounds instead of unknown scalars. That removes a common rejection when code indexes with results such as a masked shift or a hash modulo CPU count.

Scalar evolution now summarises more loop shapes in a single pass: partial spills, bounds in read-only data, counters on the stack, multiple back edges, signed downward counts that cross zero, and compiler-generated flag latches. The verifier therefore avoids unrolling many for and while loops one iteration at a time. Starovoitov reports that no programs from sched-ext, Cilium, the selftests or Meta’s public set are lost, while several GCC-built profiler hooks and scx programs now load; some scx programs also shrink after better pruning.

Static subprograms are handled more carefully. Argument layout is taken from the code rather than BTF, trampolines keep that layout or the attach is refused, and the ceiling rises to 24 arguments (five registers plus 19 stack slots) and 1024 subprograms. Indirect calls through function-pointer tables may target as many entries as the subprogram limit, which matters for Rust trait objects that previously hit the old 64-target cap.

Together the changes reduce friction between modern compiler output and the verifier while preserving its safety guarantees.