All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/9] bpf: Check chains of calls over the call graph, allow 32 frames
@ 2026-11-04 21:55 Alexei Starovoitov
  2026-11-04 21:55 ` [PATCH bpf-next 1/9] bpf: Build the call graph of a prog after the main verification pass Alexei Starovoitov
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Alexei Starovoitov @ 2026-11-04 21:55 UTC (permalink / raw)
  To: bpf; +Cc: daniel, andrii, eddyz87, memxor

From: Alexei Starovoitov <ast@kernel.org>

check_max_stack_depth() walks the chains of calls of a prog one by one:

      main          main -> A -> C -> D
      /  \          main -> A -> C -> E
     A    B         main -> B -> C -> D
      \  /          main -> B -> C -> E
       C
      / \
     D   E

The number of chains grows exponentially with the number of subprogs. The
walk was made to add up the stack. Now it also looks for recursion, finds
the subprogs that get to a tail call, that run in a callback, that use
a private stack or take a stack in arena, and counts frames.

None of it depends on a chain. It depends on who calls whom. Build the call
graph and compute the same things there. Then bump MAX_CALL_FRAMES.

  patch  what moves from the walk to the graph
  -----  -------------------------------------------------------------
      1  the graph, recursion, calls of the exception callback
      2  BPF_LD_[ABS|IND] and bpf_throw() in a callback
      3  tail_call_reachable, what cannot get to a tail call
      4  callbacks that take a stack in arena
      5  private stack or kernel stack
      6  bytes of stack and of the stack in arena, frames. No walk is left
      7  tests of these rules

      8  MAX_CALL_FRAMES 16 -> 32
      9  tests with 32 and 33 frames

What users see
==============

  load time  When each of N global functions calls the next one in both
             branches of an 'if', the prog executes N calls and has 2^N
             chains. 28 such functions load in 0.7 ms and not in 24 sec.
             Patch 6 has the table.
  limit      32 call frames for JITed progs. It is what the progs of
             https://github.com/4ast/rust-bpf need. These progs do not
             load yet: they need more changes of the verifier.
  memory     mem_peak of veristat grows by 4% for the selftests, by 3% for
             sched_ext, and by 1% for Cilium (patch 8).
  verdict    A tail call in an async callback that calls nothing is
             rejected, like in all other callbacks. It can only be dead
             code: an async callback has no ctx for bpf_tail_call().
  messages   The texts are the same. The message about recursion names the
             last call of the cycle. When several subprogs go over a limit,
             the message has the numbers of the first one in the prog and
             of its longest chain. A prog that breaks two rules can get the
             other message and errno. Too many frames in a chain of calls
             that passes a pointer to the stack had -EINVAL and no message.
             Now it has -E2BIG and a message.

What counts as a call does not change.

Veristat changes
================

A: bpf-next b3b9fd4dda09. B: A with this series. The two runs use the same
objects. The selftests are those of A.

One verdict changes: global_func3 of the selftests has 17 frames and loads
in B. Each prog of the selftests, Cilium, sched_ext and Meta that loads in
the two runs has the same insns, states, size of the xlated and of the
JITed code and stack depth.

These progs have few chains of calls. The walk takes less than 0.1% of the
verification time of Cilium and sched_ext, and so does the graph.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>

Alexei Starovoitov (9):
  bpf: Build the call graph of a prog after the main verification pass
  bpf: Use the call graph to find what runs in a callback
  bpf: Use the call graph to find what gets to a tail call
  bpf: Use the call graph to find callbacks that take a stack in arena
  bpf: Use the call graph to choose subprogs with a private stack
  bpf: Use the call graph to compute the depth of chains of calls
  selftests/bpf: Test what follows from the chains of calls
  bpf: Bump MAX_CALL_FRAMES to 32
  selftests/bpf: Test 32 call frames

 include/linux/bpf_verifier.h                  |  15 +-
 kernel/bpf/liveness.c                         |  11 +-
 kernel/bpf/verifier.c                         | 699 +++++++++++-------
 .../selftests/bpf/progs/test_global_func3.c   | 181 ++++-
 .../bpf/progs/test_global_func_deep_stack.c   |  83 +++
 .../bpf/progs/verifier_arena_stack.c          |  61 ++
 .../bpf/progs/verifier_large_stack.c          |  17 +
 .../bpf/progs/verifier_private_stack.c        |  40 +
 .../selftests/bpf/progs/verifier_tailcall.c   |  78 ++
 tools/testing/selftests/bpf/verifier/calls.c  |  97 +++
 10 files changed, 993 insertions(+), 289 deletions(-)

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-11-05  1:30 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 21:55 [PATCH bpf-next 0/9] bpf: Check chains of calls over the call graph, allow 32 frames Alexei Starovoitov
2026-11-04 21:55 ` [PATCH bpf-next 1/9] bpf: Build the call graph of a prog after the main verification pass Alexei Starovoitov
2026-11-04 21:55 ` [PATCH bpf-next 2/9] bpf: Use the call graph to find what runs in a callback Alexei Starovoitov
2026-11-04 21:55 ` [PATCH bpf-next 3/9] bpf: Use the call graph to find what gets to a tail call Alexei Starovoitov
2026-11-04 21:55 ` [PATCH bpf-next 4/9] bpf: Use the call graph to find callbacks that take a stack in arena Alexei Starovoitov
2026-11-04 21:55 ` [PATCH bpf-next 5/9] bpf: Use the call graph to choose subprogs with a private stack Alexei Starovoitov
2026-11-04 21:55 ` [PATCH bpf-next 6/9] bpf: Use the call graph to compute the depth of chains of calls Alexei Starovoitov
2026-11-04 21:55 ` [PATCH bpf-next 7/9] selftests/bpf: Test what follows from the " Alexei Starovoitov
2026-11-04 21:55 ` [PATCH bpf-next 8/9] bpf: Bump MAX_CALL_FRAMES to 32 Alexei Starovoitov
2026-11-04 22:40   ` bot+bpf-ci
2026-11-05  0:32     ` Alexei Starovoitov
2026-11-04 21:55 ` [PATCH bpf-next 9/9] selftests/bpf: Test 32 call frames Alexei Starovoitov
2026-11-05  1:30 ` [PATCH bpf-next 0/9] bpf: Check chains of calls over the call graph, allow 32 frames patchwork-bot+netdevbpf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.