]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Allow sleepable programs to use LPM trie maps directly
authorVlad Poenaru <vlad.wing@gmail.com>
Tue, 9 Jun 2026 13:55:58 +0000 (06:55 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 9 Jun 2026 19:42:38 +0000 (12:42 -0700)
The previous change relaxed the rcu_dereference annotations in
lpm_trie.c so the trie walks no longer trip lockdep when reached from a
sleepable BPF program holding only rcu_read_lock_trace().  By itself
that only helps tries reached as the inner map of a map-of-maps, or
from the classic-RCU syscall path: a sleepable program that references
an LPM trie directly is still rejected at load time by
check_map_prog_compatibility(), whose sleepable whitelist omits
BPF_MAP_TYPE_LPM_TRIE:

  Sleepable programs can only use array, hash, ringbuf and local storage maps

LPM trie nodes are allocated from a bpf_mem_alloc (trie->ma) and freed
with bpf_mem_cache_free_rcu(), which chains a regular RCU grace period
into a Tasks Trace grace period before the node -- and the value
embedded in it that trie_lookup_elem() returns to the program -- is
released.  That is the same reclaim discipline BPF_MAP_TYPE_HASH relies
on for sleepable access, so a value handed to a sleepable reader cannot
be freed while the program is still running under rcu_read_lock_trace().
The writer paths take trie->lock across the walk and never relied on the
RCU read-side lock to keep nodes alive.

Add BPF_MAP_TYPE_LPM_TRIE to the sleepable map whitelist so these
programs can use LPM tries directly.

Signed-off-by: Vlad Poenaru <vlad.wing@gmail.com>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Link: https://lore.kernel.org/r/20260609135558.193287-3-vlad.wing@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index cdff3e6eb96e7b765bf41ea8528fe28a2c592c06..954b85609f321e36186a590845d26bbdda3543a4 100644 (file)
@@ -17737,6 +17737,7 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,
                case BPF_MAP_TYPE_PERCPU_HASH:
                case BPF_MAP_TYPE_PERCPU_ARRAY:
                case BPF_MAP_TYPE_LRU_PERCPU_HASH:
+               case BPF_MAP_TYPE_LPM_TRIE:
                case BPF_MAP_TYPE_ARRAY_OF_MAPS:
                case BPF_MAP_TYPE_HASH_OF_MAPS:
                case BPF_MAP_TYPE_RINGBUF: