FAILED: patch "[PATCH] bpf: Allow LPM map access from sleepable BPF programs" failed to apply to 6.12-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 2f884d371fafea137afea504d49ee4a7c8d7985b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026071449-absurd-charm-2576@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2f884d371fafea137afea504d49ee4a7c8d7985b Mon Sep 17 00:00:00 2001
From: Vlad Poenaru <[email protected]>
Date: Tue, 9 Jun 2026 06:55:57 -0700
Subject: [PATCH] bpf: Allow LPM map access from sleepable BPF programs
trie_lookup_elem() annotates its rcu_dereference_check() walks with only rcu_read_lock_bh_held(). Because rcu_dereference_check(p, c) resolves to "c || rcu_read_lock_held()", this passes for XDP/NAPI and classic RCU readers but fails for sleepable BPF programs, which enter via __bpf_prog_enter_sleepable() and hold only rcu_read_lock_trace().
trie_update_elem() and trie_delete_elem() have the same problem in a different form: they walk the trie with plain rcu_dereference(), which asserts rcu_read_lock_held() unconditionally. Both are reachable from sleepable BPF programs via the bpf_map_update_elem / bpf_map_delete_elem helpers, and from the syscall path under classic rcu_read_lock(). In the writer paths the trie is actually protected by trie->lock (an rqspinlock taken across the walk); we never relied on the RCU read-side lock to keep nodes alive there.
A sleepable LSM hook that ends up touching an LPM trie therefore triggers lockdep on debug kernels:
=============================
WARNING: suspicious RCU usage
7.1.0-... Tainted: G E
-----------------------------
kernel/bpf/lpm_trie.c:249 suspicious rcu_dereference_check() usage! 1 lock held by net_tests/540:
#0: (rcu_tasks_trace_srcu_struct){....}-{0:0},
at: __bpf_prog_enter_sleepable+0x26/0x280 Call Trace: dump_stack_lvl lockdep_rcu_suspicious trie_lookup_elem bpf_prog_..._enforce_security_socket_connect bpf_trampoline_... security_socket_connect __sys_connect do_syscall_64
This is lockdep-only -- no UAF, since Tasks Trace RCU does serialize against the trie's reclaim path -- but it spams the console once per distinct callsite on every debug kernel running a sleepable BPF LSM that touches an LPM trie, which is increasingly common.
For the lookup path, switch the rcu_dereference_check() annotation from rcu_read_lock_bh_held() to bpf_rcu_lock_held(), which accepts all three contexts (classic, BH, Tasks Trace). Other map types already follow this convention.
For trie_update_elem() and trie_delete_elem(), annotate the walks as rcu_dereference_protected(*p, 1) -- matching trie_free() in the same file -- since trie->lock is held across the walk. rqspinlock has no lockdep_map, so the predicate degenerates to '1' rather than lockdep_is_held(&trie->lock); the protection is real but not machine-verifiable. trie_get_next_key() also uses bare rcu_dereference() but is reachable only from the BPF syscall, which holds classic rcu_read_lock() before dispatching, so it is left untouched.
kernel/bpf/lpm_trie.c +4 -4
@@ -246,7 +246,7 @@ static void *trie_lookup_elem(struct bpf_map *map, void *_key)/* Start walking the trie from the root node ... */ -for (node =rcu_dereference_check (trie->root,rcu_read_lock_bh_held ()); +for (node =rcu_dereference_check (trie->root,bpf_rcu_lock_held ()); node;) {unsigned int next_bit;size_t matchlen;
@@ -280,7 +280,7 @@ static void *trie_lookup_elem(struct bpf_map *map, void *_key)*/ next_bit =extract_bit (key->data, node->prefixlen); node =rcu_dereference_check (node->child[next_bit], -rcu_read_lock_bh_held ()); +bpf_rcu_lock_held ()); }if (!found)
@@ -359,7 +359,7 @@ static long trie_update_elem(struct bpf_map *map,*/ slot = &trie->root; -while ((node =rcu_dereference (*slot))) { +while ((node =rcu_dereference_protected (*slot,1 ))) { matchlen =longest_prefix_match (trie, node, key); if (node->prefixlen != matchlen ||
@@ -482,7 +482,7 @@ static long trie_delete_elem(struct bpf_map *map, void *_key) trim = &trie->root; trim2 = trim; parent =NULL ; -while ((node =rcu_dereference (*trim))) { +while ((node =rcu_dereference_protected (*trim,1 ))) { matchlen =longest_prefix_match (trie, node, key); if (node->prefixlen != matchlen ||
Sasha Levin
maintainerPATCH 1/4 bpf: Convert lpm_trie.c to rqspinlock
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit 47979314c0fe245ed54306e2f91b3f819c7c0f9f ]
Convert all LPM trie usage of raw_spinlock to rqspinlock.
Note that rcu_dereference_protected in trie_delete_elem is switched over to plain rcu_dereference, the RCU read lock should be held from BPF program side or eBPF syscall path, and the trie->lock is just acquired before the dereference. It is not clear the reason the protected variant was used from the commit history, but the above reasoning makes sense so switch over.
Stable-dep-of: 2f884d371faf ("bpf: Allow LPM map access from sleepable BPF programs")
--- kernel/bpf/lpm_trie.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
kernel/bpf/lpm_trie.c +3 -4
@@ -15,6 +15,7 @@#include <net/ipv6.h> #include <uapi/linux/btf.h> #include <linux/btf_ids.h> +#include <linux/bpf_local_storage.h> /* Intermediate node */ #define LPM_TREE_NODE_FLAG_IM BIT(0)
@@ -361,8 +362,7 @@ static long trie_update_elem(struct bpf_map *map,*/ slot = &trie->root; -while ((node =rcu_dereference_protected (*slot, -lockdep_is_held (&trie->lock)))) { +while ((node =rcu_dereference (*slot))) { matchlen =longest_prefix_match (trie, node, key); if (node->prefixlen != matchlen ||
@@ -483,8 +483,7 @@ static long trie_delete_elem(struct bpf_map *map, void *_key) trim = &trie->root; trim2 = trim; parent =NULL ; -while ((node =rcu_dereference_protected ( - *trim,lockdep_is_held (&trie->lock)))) { +while ((node =rcu_dereference (*trim))) { matchlen =longest_prefix_match (trie, node, key); if (node->prefixlen != matchlen ||
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/4 bpf, arm64, powerpc: Add bpf_jit_bypass_spec_v1/v4()
From: Luis Gerhorst <[email protected]>
[ Upstream commit 03c68a0f8c68936a0bb915b030693923784724cb ]
JITs can set bpf_jit_bypass_spec_v1/v4() if they want the verifier to skip analysis/patching for the respective vulnerability. For v4, this will reduce the number of barriers the verifier inserts. For v1, it allows more programs to be accepted.
The primary motivation for this is to not regress unpriv BPF's performance on ARM64 in a future commit where BPF_NOSPEC is also used against Spectre v1.
This has the user-visible change that v1-induced rejections on non-vulnerable PowerPC CPUs are avoided.
For now, this does not change the semantics of BPF_NOSPEC. It is still a v4-only barrier and must not be implemented if bypass_spec_v4 is always true for the arch. Changing it to a v1 AND v4-barrier is done in a future commit.
As an alternative to bypass_spec_v1/v4, one could introduce NOSPEC_V1 AND NOSPEC_V4 instructions and allow backends to skip their lowering as suggested by commit f5e81d111750 ("bpf: Introduce BPF nospec instruction for mitigating Spectre v4"). Adding bpf_jit_bypass_spec_v1/v4() was found to be preferable for the following reason:
* bypass_spec_v1/v4 benefits non-vulnerable CPUs: Always performing the same analysis (not taking into account whether the current CPU is vulnerable), needlessly restricts users of CPUs that are not vulnerable. The only use case for this would be portability-testing, but this can later be added easily when needed by allowing users to force bypass_spec_v1/v4 to false.
* Portability is still acceptable: Directly disabling the analysis instead of skipping the lowering of BPF_NOSPEC(_V1/V4) might allow programs on non-vulnerable CPUs to be accepted while the program will be rejected on vulnerable CPUs. With the fallback to speculation barriers for Spectre v1 implemented in a future commit, this will only affect programs that do variable stack-accesses or are very complex.
For PowerPC, the SEC_FTR checking in bpf_jit_bypass_spec_v4() is based on the check that was previously located in the BPF_NOSPEC case.
For LoongArch, it would likely be safe to set both bpf_jit_bypass_spec_v1() and _v4() according to
commit a6f6a95f2580 ("LoongArch, bpf: Fix jit to skip speculation barrier opcode"). This is omitted here as I am unable to do any testing for LoongArch.
Hari's ack concerns the PowerPC part only.
Stable-dep-of: 2f884d371faf ("bpf: Allow LPM map access from sleepable BPF programs")
--- arch/arm64/net/bpf_jit_comp.c | 21 ++++++++++++--------- arch/powerpc/net/bpf_jit_comp64.c | 21 +++++++++++++++++---- include/linux/bpf.h | 11 +++++++++-- kernel/bpf/core.c | 15 +++++++++++++++ 4 files changed, 53 insertions(+), 15 deletions(-)
arch/arm64/net/bpf_jit_comp.c +12 -9
@@ -1558,15 +1558,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,/* speculation barrier */ case BPF_ST |BPF_NOSPEC : -/* -* Nothing required here. -* -* In case of arm64, we rely on the firmware mitigation of -* Speculative Store Bypass as controlled via the ssbd kernel -* parameter. Whenever the mitigation is enabled, it works -* for all of the kernel code with no need to provide any -* additional instructions. -*/ +/* See bpf_jit_bypass_spec_v4() */ break ;/* ST: *(size *)(dst + off) = imm */
@@ -2730,6 +2722,17 @@ bool bpf_jit_supports_percpu_insn(void)return true; } +bool bpf_jit_bypass_spec_v4 (void ) +{ +/* In case of arm64, we rely on the firmware mitigation of Speculative +* Store Bypass as controlled via the ssbd kernel parameter. Whenever +* the mitigation is enabled, it works for all of the kernel code with +* no need to provide any additional instructions. Therefore, skip +* inserting nospec insns against Spectre v4. +*/ +return true; +} +bool bpf_jit_inlines_helper_call (s32 imm) {switch (imm) {
arch/powerpc/net/bpf_jit_comp64.c +17 -4
@@ -440,6 +440,23 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 oreturn 0 ; } +bool bpf_jit_bypass_spec_v1 (void ) +{ +#if defined(CONFIG_PPC_E500 ) || defined(CONFIG_PPC_BOOK3S_64 ) +return !(security_ftr_enabled (SEC_FTR_FAVOUR_SECURITY ) && +security_ftr_enabled (SEC_FTR_BNDS_CHK_SPEC_BAR )); +#else +return true; +#endif +} + +bool bpf_jit_bypass_spec_v4 (void ) +{ +return !(security_ftr_enabled (SEC_FTR_FAVOUR_SECURITY ) && +security_ftr_enabled (SEC_FTR_STF_BARRIER ) && +stf_barrier_type_get () !=STF_BARRIER_NONE ); +} +/* * We spill into the redzone always, even if the bpf program has its own stackframe. * Offsets hardcoded based on BPF_PPC_STACK_SAVE -- see bpf_jit_stack_local()
@@ -864,10 +881,6 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code* BPF_ST NOSPEC (speculation barrier) */ case BPF_ST |BPF_NOSPEC : -if (!security_ftr_enabled (SEC_FTR_FAVOUR_SECURITY ) || - !security_ftr_enabled (SEC_FTR_STF_BARRIER )) -break ; -switch (stf_barrier) {case STF_BARRIER_EIEIO :EMIT (PPC_RAW_EIEIO () |0x02000000 );
include/linux/bpf.h +9 -2
@@ -2216,6 +2216,9 @@ bpf_prog_run_array_uprobe(const struct bpf_prog_array *array,return ret; } +bool bpf_jit_bypass_spec_v1 (void ); +bool bpf_jit_bypass_spec_v4 (void ); +#ifdef CONFIG_BPF_SYSCALL DECLARE_PER_CPU (int, bpf_prog_active);extern struct mutex bpf_stats_enabled_mutex;
@@ -2386,12 +2389,16 @@ static inline bool bpf_allow_uninit_stack(const struct bpf_token *token)static inline bool bpf_bypass_spec_v1 (const struct bpf_token *token) { -return cpu_mitigations_off () ||bpf_token_capable (token,CAP_PERFMON ); +return bpf_jit_bypass_spec_v1 () || +cpu_mitigations_off () || +bpf_token_capable (token,CAP_PERFMON ); }static inline bool bpf_bypass_spec_v4 (const struct bpf_token *token) { -return cpu_mitigations_off () ||bpf_token_capable (token,CAP_PERFMON ); +return bpf_jit_bypass_spec_v4 () || +cpu_mitigations_off () || +bpf_token_capable (token,CAP_PERFMON ); }int bpf_map_new_fd (struct bpf_map *map,int flags);
kernel/bpf/core.c +15 -0
@@ -3032,6 +3032,21 @@ bool __weak bpf_jit_needs_zext(void)return false; } +/* By default, enable the verifier's mitigations against Spectre v1 and v4 for +* all archs. The value returned must not change at runtime as there is +* currently no support for reloading programs that were loaded without +* mitigations. +*/ +bool __weak bpf_jit_bypass_spec_v1 (void ) +{ +return false; +} + +bool __weak bpf_jit_bypass_spec_v4 (void ) +{ +return false; +} +/* Return true if the JIT inlines the call to the helper corresponding to * the imm. *
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/4 bpf: Consistently use bpf_rcu_lock_held() everywhere
In reply to Sasha LevinFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit 48a97ffc6c826640907d13b199e29008f4fe2c15 ]
We have many places which open-code what's now is bpf_rcu_lock_held() macro, so replace all those places with a clean and short macro invocation. For that, move bpf_rcu_lock_held() macro into include/linux/bpf.h.
Stable-dep-of: 2f884d371faf ("bpf: Allow LPM map access from sleepable BPF programs")
--- include/linux/bpf.h | 3 +++ include/linux/bpf_local_storage.h | 3 --- kernel/bpf/hashtab.c | 21 +++++++-------------- kernel/bpf/helpers.c | 12 ++++-------- 4 files changed, 14 insertions(+), 25 deletions(-)
include/linux/bpf.h +3 -0
@@ -2219,6 +2219,9 @@ bpf_prog_run_array_uprobe(const struct bpf_prog_array *array,bool bpf_jit_bypass_spec_v1 (void );bool bpf_jit_bypass_spec_v4 (void ); +#define bpf_rcu_lock_held () \ + (rcu_read_lock_held() || rcu_read_lock_trace_held() || rcu_read_lock_bh_held()) +#ifdef CONFIG_BPF_SYSCALL DECLARE_PER_CPU (int, bpf_prog_active);extern struct mutex bpf_stats_enabled_mutex;
include/linux/bpf_local_storage.h +0 -3
@@ -18,9 +18,6 @@#define BPF_LOCAL_STORAGE_CACHE_SIZE 16 -#define bpf_rcu_lock_held () \ - (rcu_read_lock_held() || rcu_read_lock_trace_held() || \ - rcu_read_lock_bh_held())struct bpf_local_storage_map_bucket {struct hlist_head list;raw_spinlock_t lock;
kernel/bpf/hashtab.c +7 -14
@@ -685,8 +685,7 @@ static void *__htab_map_lookup_elem(struct bpf_map *map, void *key)struct htab_elem *l;u32 hash, key_size; -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ()); key_size = map->key_size;
@@ -1122,8 +1121,7 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value,/* unknown flags */ return -EINVAL ; -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ()); key_size = map->key_size;
@@ -1240,8 +1238,7 @@ static long htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value/* unknown flags */ return -EINVAL ; -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ()); key_size = map->key_size;
@@ -1309,8 +1306,7 @@ static long __htab_percpu_map_update_elem(struct bpf_map *map, void *key,/* unknown flags */ return -EINVAL ; -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ()); key_size = map->key_size;
@@ -1364,8 +1360,7 @@ static long __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key,/* unknown flags */ return -EINVAL ; -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ()); key_size = map->key_size;
@@ -1442,8 +1437,7 @@ static long htab_map_delete_elem(struct bpf_map *map, void *key)u32 hash, key_size;int ret; -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ()); key_size = map->key_size;
@@ -1478,8 +1472,7 @@ static long htab_lru_map_delete_elem(struct bpf_map *map, void *key)u32 hash, key_size;int ret; -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ()); key_size = map->key_size;
kernel/bpf/helpers.c +4 -8
@@ -37,8 +37,7 @@*/ BPF_CALL_2(bpf_map_lookup_elem, struct bpf_map *, map, void *, key) { -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ());return (unsigned long ) map->ops->map_lookup_elem (map, key); }
@@ -54,8 +53,7 @@ const struct bpf_func_proto bpf_map_lookup_elem_proto = { BPF_CALL_4(bpf_map_update_elem, struct bpf_map *, map, void *, key, void *, value, u64, flags) { -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ());return map->ops->map_update_elem (map, key, value, flags); }
@@ -72,8 +70,7 @@ const struct bpf_func_proto bpf_map_update_elem_proto = { BPF_CALL_2(bpf_map_delete_elem, struct bpf_map *, map, void *, key) { -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ());return map->ops->map_delete_elem (map, key); }
@@ -129,8 +126,7 @@ const struct bpf_func_proto bpf_map_peek_elem_proto = { BPF_CALL_3(bpf_map_lookup_percpu_elem, struct bpf_map *, map, void *, key, u32, cpu) { -WARN_ON_ONCE (!rcu_read_lock_held () && !rcu_read_lock_trace_held () && - !rcu_read_lock_bh_held ()); +WARN_ON_ONCE (!bpf_rcu_lock_held ());return (unsigned long ) map->ops->map_lookup_percpu_elem (map, key, cpu); }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/4 bpf: Allow LPM map access from sleepable BPF programs
In reply to Sasha LevinFrom: Vlad Poenaru <[email protected]>
[ Upstream commit 2f884d371fafea137afea504d49ee4a7c8d7985b ]
trie_lookup_elem() annotates its rcu_dereference_check() walks with only rcu_read_lock_bh_held(). Because rcu_dereference_check(p, c) resolves to "c || rcu_read_lock_held()", this passes for XDP/NAPI and classic RCU readers but fails for sleepable BPF programs, which enter via __bpf_prog_enter_sleepable() and hold only rcu_read_lock_trace().
trie_update_elem() and trie_delete_elem() have the same problem in a different form: they walk the trie with plain rcu_dereference(), which asserts rcu_read_lock_held() unconditionally. Both are reachable from sleepable BPF programs via the bpf_map_update_elem / bpf_map_delete_elem helpers, and from the syscall path under classic rcu_read_lock(). In the writer paths the trie is actually protected by trie->lock (an rqspinlock taken across the walk); we never relied on the RCU read-side lock to keep nodes alive there.
A sleepable LSM hook that ends up touching an LPM trie therefore triggers lockdep on debug kernels:
=============================
WARNING: suspicious RCU usage
7.1.0-... Tainted: G E
-----------------------------
kernel/bpf/lpm_trie.c:249 suspicious rcu_dereference_check() usage! 1 lock held by net_tests/540:
#0: (rcu_tasks_trace_srcu_struct){....}-{0:0},
at: __bpf_prog_enter_sleepable+0x26/0x280 Call Trace: dump_stack_lvl lockdep_rcu_suspicious trie_lookup_elem bpf_prog_..._enforce_security_socket_connect bpf_trampoline_... security_socket_connect __sys_connect do_syscall_64
This is lockdep-only -- no UAF, since Tasks Trace RCU does serialize against the trie's reclaim path -- but it spams the console once per distinct callsite on every debug kernel running a sleepable BPF LSM that touches an LPM trie, which is increasingly common.
For the lookup path, switch the rcu_dereference_check() annotation from rcu_read_lock_bh_held() to bpf_rcu_lock_held(), which accepts all three contexts (classic, BH, Tasks Trace). Other map types already follow this convention.
For trie_update_elem() and trie_delete_elem(), annotate the walks as rcu_dereference_protected(*p, 1) -- matching trie_free() in the same file -- since trie->lock is held across the walk. rqspinlock has no lockdep_map, so the predicate degenerates to '1' rather than lockdep_is_held(&trie->lock); the protection is real but not machine-verifiable. trie_get_next_key() also uses bare rcu_dereference() but is reachable only from the BPF syscall, which holds classic rcu_read_lock() before dispatching, so it is left untouched.
--- kernel/bpf/lpm_trie.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
kernel/bpf/lpm_trie.c +4 -4
@@ -245,7 +245,7 @@ static void *trie_lookup_elem(struct bpf_map *map, void *_key)/* Start walking the trie from the root node ... */ -for (node =rcu_dereference_check (trie->root,rcu_read_lock_bh_held ()); +for (node =rcu_dereference_check (trie->root,bpf_rcu_lock_held ()); node;) {unsigned int next_bit;size_t matchlen;
@@ -279,7 +279,7 @@ static void *trie_lookup_elem(struct bpf_map *map, void *_key)*/ next_bit =extract_bit (key->data, node->prefixlen); node =rcu_dereference_check (node->child[next_bit], -rcu_read_lock_bh_held ()); +bpf_rcu_lock_held ()); }if (!found)
@@ -362,7 +362,7 @@ static long trie_update_elem(struct bpf_map *map,*/ slot = &trie->root; -while ((node =rcu_dereference (*slot))) { +while ((node =rcu_dereference_protected (*slot,1 ))) { matchlen =longest_prefix_match (trie, node, key); if (node->prefixlen != matchlen ||
@@ -483,7 +483,7 @@ static long trie_delete_elem(struct bpf_map *map, void *_key) trim = &trie->root; trim2 = trim; parent =NULL ; -while ((node =rcu_dereference (*trim))) { +while ((node =rcu_dereference_protected (*trim,1 ))) { matchlen =longest_prefix_match (trie, node, key); if (node->prefixlen != matchlen ||
Signature · 1 line
2.53.0