]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Convert bpf_selem_link_map to failable
authorAmery Hung <ameryhung@gmail.com>
Thu, 5 Feb 2026 22:29:01 +0000 (14:29 -0800)
committerMartin KaFai Lau <martin.lau@kernel.org>
Fri, 6 Feb 2026 22:28:55 +0000 (14:28 -0800)
To prepare for changing bpf_local_storage_map_bucket::lock to rqspinlock,
convert bpf_selem_link_map() to failable. It still always succeeds and
returns 0 until the change happens. No functional change.

Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://patch.msgid.link/20260205222916.1788211-4-ameryhung@gmail.com
include/linux/bpf_local_storage.h
kernel/bpf/bpf_local_storage.c
net/core/bpf_sk_storage.c

index 2638487425b8934592a29cb9d9be857c8d2fa416..709506e982a6272c7da9e0e50a69c77164606bb2 100644 (file)
@@ -178,9 +178,9 @@ void bpf_selem_link_storage_nolock(struct bpf_local_storage *local_storage,
 
 void bpf_selem_unlink(struct bpf_local_storage_elem *selem, bool reuse_now);
 
-void bpf_selem_link_map(struct bpf_local_storage_map *smap,
-                       struct bpf_local_storage *local_storage,
-                       struct bpf_local_storage_elem *selem);
+int bpf_selem_link_map(struct bpf_local_storage_map *smap,
+                      struct bpf_local_storage *local_storage,
+                      struct bpf_local_storage_elem *selem);
 
 struct bpf_local_storage_elem *
 bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner, void *value,
index 6fa71502c7d716e272b508ea57411654c6c92466..2f94ca4a4475b50bd1c2f05b929bd9a2d505b235 100644 (file)
@@ -365,9 +365,9 @@ static void bpf_selem_unlink_map_nolock(struct bpf_local_storage_elem *selem)
        hlist_del_init_rcu(&selem->map_node);
 }
 
-void bpf_selem_link_map(struct bpf_local_storage_map *smap,
-                       struct bpf_local_storage *local_storage,
-                       struct bpf_local_storage_elem *selem)
+int bpf_selem_link_map(struct bpf_local_storage_map *smap,
+                      struct bpf_local_storage *local_storage,
+                      struct bpf_local_storage_elem *selem)
 {
        struct bpf_local_storage_map_bucket *b;
        unsigned long flags;
@@ -376,6 +376,8 @@ void bpf_selem_link_map(struct bpf_local_storage_map *smap,
        raw_spin_lock_irqsave(&b->lock, flags);
        hlist_add_head_rcu(&selem->map_node, &b->list);
        raw_spin_unlock_irqrestore(&b->lock, flags);
+
+       return 0;
 }
 
 static void bpf_selem_link_map_nolock(struct bpf_local_storage_map_bucket *b,
index e36273e4fcbdb0db6d54c5ef788ee8b12cd07062..0b85d8f2c17eb8bbd1e21c3916c35a22437657d3 100644 (file)
@@ -191,7 +191,14 @@ int bpf_sk_storage_clone(const struct sock *sk, struct sock *newsk)
                }
 
                if (new_sk_storage) {
-                       bpf_selem_link_map(smap, new_sk_storage, copy_selem);
+                       ret = bpf_selem_link_map(smap, new_sk_storage, copy_selem);
+                       if (ret) {
+                               bpf_selem_free(copy_selem, true);
+                               atomic_sub(smap->elem_size,
+                                          &newsk->sk_omem_alloc);
+                               bpf_map_put(map);
+                               goto out;
+                       }
                        bpf_selem_link_storage_nolock(new_sk_storage, copy_selem);
                } else {
                        ret = bpf_local_storage_alloc(newsk, smap, copy_selem, GFP_ATOMIC);