Skip to content

Commit 6a5c63d

Browse files
Hou TaoAlexei Starovoitov
authored andcommitted
bpf: Use raw_spinlock_t for LPM trie
After switching from kmalloc() to the bpf memory allocator, there will be no blocking operation during the update of LPM trie. Therefore, change trie->lock from spinlock_t to raw_spinlock_t to make LPM trie usable in atomic context, even on RT kernels. The max value of prefixlen is 2048. Therefore, update or deletion operations will find the target after at most 2048 comparisons. Constructing a test case which updates an element after 2048 comparisons under a 8 CPU VM, and the average time and the maximal time for such update operation is about 210us and 900us. Signed-off-by: Hou Tao <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 3d8dc43 commit 6a5c63d

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

kernel/bpf/lpm_trie.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct lpm_trie {
3636
size_t n_entries;
3737
size_t max_prefixlen;
3838
size_t data_size;
39-
spinlock_t lock;
39+
raw_spinlock_t lock;
4040
};
4141

4242
/* This trie implements a longest prefix match algorithm that can be used to
@@ -349,7 +349,7 @@ static long trie_update_elem(struct bpf_map *map,
349349
if (!new_node)
350350
return -ENOMEM;
351351

352-
spin_lock_irqsave(&trie->lock, irq_flags);
352+
raw_spin_lock_irqsave(&trie->lock, irq_flags);
353353

354354
new_node->prefixlen = key->prefixlen;
355355
RCU_INIT_POINTER(new_node->child[0], NULL);
@@ -450,7 +450,7 @@ static long trie_update_elem(struct bpf_map *map,
450450
rcu_assign_pointer(*slot, im_node);
451451

452452
out:
453-
spin_unlock_irqrestore(&trie->lock, irq_flags);
453+
raw_spin_unlock_irqrestore(&trie->lock, irq_flags);
454454

455455
migrate_disable();
456456
if (ret)
@@ -477,7 +477,7 @@ static long trie_delete_elem(struct bpf_map *map, void *_key)
477477
if (key->prefixlen > trie->max_prefixlen)
478478
return -EINVAL;
479479

480-
spin_lock_irqsave(&trie->lock, irq_flags);
480+
raw_spin_lock_irqsave(&trie->lock, irq_flags);
481481

482482
/* Walk the tree looking for an exact key/length match and keeping
483483
* track of the path we traverse. We will need to know the node
@@ -553,7 +553,7 @@ static long trie_delete_elem(struct bpf_map *map, void *_key)
553553
free_node = node;
554554

555555
out:
556-
spin_unlock_irqrestore(&trie->lock, irq_flags);
556+
raw_spin_unlock_irqrestore(&trie->lock, irq_flags);
557557

558558
migrate_disable();
559559
bpf_mem_cache_free_rcu(&trie->ma, free_parent);
@@ -604,7 +604,7 @@ static struct bpf_map *trie_alloc(union bpf_attr *attr)
604604
offsetof(struct bpf_lpm_trie_key_u8, data);
605605
trie->max_prefixlen = trie->data_size * 8;
606606

607-
spin_lock_init(&trie->lock);
607+
raw_spin_lock_init(&trie->lock);
608608

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

0 commit comments

Comments
 (0)