summaryrefslogtreecommitdiff
path: root/include/linux/bpf_verifier.h
diff options
context:
space:
mode:
authorKumar Kartikeya Dwivedi <memxor@gmail.com>2026-09-24 18:57:09 +0200
committerAlexei Starovoitov <ast@kernel.org>2026-09-24 18:04:45 +0000
commit9f3d900a69be7e52d82bc06577d55a33cc41c30c (patch)
tree380587ca7e8981289efb2844d5cf18bd5eff2f19 /include/linux/bpf_verifier.h
parent481ceda77aeb180022a3ab1e17a9929bcad353c9 (diff)
bpf: Grow the verifier id scratch on demand
The id map used to compare the ids of two states, which also serves as the id stack of release_reference() and as the id set of bpf_clear_singular_ids(), is a fixed array embedded in struct bpf_verifier_env and sized for the most registers and stack slots a state can possibly hold: 1312 entries, 10 KiB, for 512-byte frames, and four times that once frames may reach 2 KiB, which pushes the env allocation from 64 KiB to 128 KiB for every program verified. States compare a few dozen ids in practice. Turn the map and the set into arrays grown on demand, starting at 64 entries and doubling, and free them with the env. A map that cannot grow treats the states as different, an id set that cannot grow keeps every id of the state, since its counts are then incomplete, and the id stack reports -ENOMEM, which release_reference() hands to its callers. The iterator destroy path used to warn on any failure of release_reference(), which could only come from a bug while the id stack could not run out of room; it now returns -ENOMEM and keeps warning about anything else. An allocation failure thus fails the load and is never unsafe. This removes the last structure whose size scaled with the stack bound and shrinks the env by 10 KiB. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20260924165740.2146806-9-memxor@gmail.com
Diffstat (limited to 'include/linux/bpf_verifier.h')
-rw-r--r--include/linux/bpf_verifier.h29
1 files changed, 17 insertions, 12 deletions
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index d3c31105a3ac..c5f2e18b7e54 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -409,10 +409,7 @@ struct bpf_jmp_history_entry {
static_assert(MAX_CALL_FRAMES <= (1 << 4));
static_assert(MAX_BPF_STACK_SLOTS <= (1 << 12));
-/* Maximum number of bpf_reg_state objects that can exist at once */
#define MAX_STACK_ARG_SLOTS (MAX_BPF_FUNC_ARGS - MAX_BPF_FUNC_REG_ARGS)
-#define BPF_ID_MAP_SIZE ((MAX_BPF_REG + MAX_BPF_STACK_SLOTS + MAX_STACK_ARG_SLOTS) * \
- MAX_CALL_FRAMES)
struct bpf_verifier_state {
/* call stack tracking */
struct bpf_func_state *frame[MAX_CALL_FRAMES];
@@ -863,18 +860,27 @@ struct bpf_id_pair {
u32 cur;
};
+/*
+ * Scratch map from the ids of one verifier state to those of another, also
+ * used as a stack of ids. Grown on demand by bpf_id_scratch_reserve().
+ */
struct bpf_idmap {
u32 tmp_id_gen;
u32 cnt;
- struct bpf_id_pair map[BPF_ID_MAP_SIZE];
+ u32 cap;
+ struct bpf_id_pair *map;
};
+struct bpf_idset_entry {
+ u32 id;
+ u32 cnt;
+};
+
+/* Scratch set of ids with a use count each, grown on demand */
struct bpf_idset {
u32 num_ids;
- struct {
- u32 id;
- u32 cnt;
- } entries[BPF_ID_MAP_SIZE];
+ u32 cap;
+ struct bpf_idset_entry *entries;
};
/* see verifier.c:compute_scc_callchain() */
@@ -983,10 +989,8 @@ struct bpf_verifier_env {
* via callx. Allocated when the first such edge is recorded.
*/
unsigned long *callx_edges;
- union {
- struct bpf_idmap idmap_scratch;
- struct bpf_idset idset_scratch;
- };
+ struct bpf_idmap idmap_scratch;
+ struct bpf_idset idset_scratch;
struct {
int *insn_state;
int *insn_stack;
@@ -1252,6 +1256,7 @@ int bpf_copy_verifier_state(struct bpf_verifier_state *dst_state,
struct list_head *bpf_explored_state(struct bpf_verifier_env *env, int idx);
void bpf_free_verifier_state(struct bpf_verifier_state *state, bool free_self);
void bpf_free_backedges(struct bpf_scc_visit *visit);
+bool bpf_id_scratch_reserve(void **arr, u32 *cap, u32 cnt, size_t elem_size);
int bpf_push_jmp_history(struct bpf_verifier_env *env, struct bpf_verifier_state *cur,
int insn_flags, int spi, int frame, const u16 *linked_regs,
u8 linked_regs_cnt);