Skip to content

Commit 4797931

Browse files
kkdwivediAlexei Starovoitov
authored andcommitted
bpf: Convert lpm_trie.c to rqspinlock
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. Closes: https://lore.kernel.org/lkml/000000000000adb08b061413919e@google.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20250316040541.108729-22-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent f2ac0e5 commit 4797931

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

kernel/bpf/lpm_trie.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <net/ipv6.h>
1616
#include <uapi/linux/btf.h>
1717
#include <linux/btf_ids.h>
18+
#include <asm/rqspinlock.h>
1819
#include <linux/bpf_mem_alloc.h>
1920

2021
/* Intermediate node */
@@ -36,7 +37,7 @@ struct lpm_trie {
3637
size_t n_entries;
3738
size_t max_prefixlen;
3839
size_t data_size;
39-
raw_spinlock_t lock;
40+
rqspinlock_t lock;
4041
};
4142

4243
/* This trie implements a longest prefix match algorithm that can be used to
@@ -342,7 +343,9 @@ static long trie_update_elem(struct bpf_map *map,
342343
if (!new_node)
343344
return -ENOMEM;
344345

345-
raw_spin_lock_irqsave(&trie->lock, irq_flags);
346+
ret = raw_res_spin_lock_irqsave(&trie->lock, irq_flags);
347+
if (ret)
348+
goto out_free;
346349

347350
new_node->prefixlen = key->prefixlen;
348351
RCU_INIT_POINTER(new_node->child[0], NULL);
@@ -356,8 +359,7 @@ static long trie_update_elem(struct bpf_map *map,
356359
*/
357360
slot = &trie->root;
358361

359-
while ((node = rcu_dereference_protected(*slot,
360-
lockdep_is_held(&trie->lock)))) {
362+
while ((node = rcu_dereference(*slot))) {
361363
matchlen = longest_prefix_match(trie, node, key);
362364

363365
if (node->prefixlen != matchlen ||
@@ -442,8 +444,8 @@ static long trie_update_elem(struct bpf_map *map,
442444
rcu_assign_pointer(*slot, im_node);
443445

444446
out:
445-
raw_spin_unlock_irqrestore(&trie->lock, irq_flags);
446-
447+
raw_res_spin_unlock_irqrestore(&trie->lock, irq_flags);
448+
out_free:
447449
if (ret)
448450
bpf_mem_cache_free(&trie->ma, new_node);
449451
bpf_mem_cache_free_rcu(&trie->ma, free_node);
@@ -467,7 +469,9 @@ static long trie_delete_elem(struct bpf_map *map, void *_key)
467469
if (key->prefixlen > trie->max_prefixlen)
468470
return -EINVAL;
469471

470-
raw_spin_lock_irqsave(&trie->lock, irq_flags);
472+
ret = raw_res_spin_lock_irqsave(&trie->lock, irq_flags);
473+
if (ret)
474+
return ret;
471475

472476
/* Walk the tree looking for an exact key/length match and keeping
473477
* track of the path we traverse. We will need to know the node
@@ -478,8 +482,7 @@ static long trie_delete_elem(struct bpf_map *map, void *_key)
478482
trim = &trie->root;
479483
trim2 = trim;
480484
parent = NULL;
481-
while ((node = rcu_dereference_protected(
482-
*trim, lockdep_is_held(&trie->lock)))) {
485+
while ((node = rcu_dereference(*trim))) {
483486
matchlen = longest_prefix_match(trie, node, key);
484487

485488
if (node->prefixlen != matchlen ||
@@ -543,7 +546,7 @@ static long trie_delete_elem(struct bpf_map *map, void *_key)
543546
free_node = node;
544547

545548
out:
546-
raw_spin_unlock_irqrestore(&trie->lock, irq_flags);
549+
raw_res_spin_unlock_irqrestore(&trie->lock, irq_flags);
547550

548551
bpf_mem_cache_free_rcu(&trie->ma, free_parent);
549552
bpf_mem_cache_free_rcu(&trie->ma, free_node);
@@ -592,7 +595,7 @@ static struct bpf_map *trie_alloc(union bpf_attr *attr)
592595
offsetof(struct bpf_lpm_trie_key_u8, data);
593596
trie->max_prefixlen = trie->data_size * 8;
594597

595-
raw_spin_lock_init(&trie->lock);
598+
raw_res_spin_lock_init(&trie->lock);
596599

597600
/* Allocate intermediate and leaf nodes from the same allocator */
598601
leaf_size = sizeof(struct lpm_trie_node) + trie->data_size +

0 commit comments

Comments
 (0)