]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Remove smap argument from bpf_selem_free()
authorAmery Hung <ameryhung@gmail.com>
Fri, 14 Nov 2025 20:13:24 +0000 (12:13 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 19 Nov 2025 00:20:25 +0000 (16:20 -0800)
Since selem already saves a pointer to smap, use it instead of an
additional argument in bpf_selem_free(). This requires moving the
SDATA(selem)->smap assignment from bpf_selem_link_map() to
bpf_selem_alloc() since bpf_selem_free() may be called without the
selem being linked to smap in bpf_local_storage_update().

Signed-off-by: Amery Hung <ameryhung@gmail.com>
Reviewed-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20251114201329.3275875-3-ameryhung@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/linux/bpf_local_storage.h
kernel/bpf/bpf_local_storage.c
net/core/bpf_sk_storage.c

index 3663eabcc3ffff213162ede90cd7fb6fd61d855f..4ab137e75f33dcb7327233586078a7ce2f6483fd 100644 (file)
@@ -187,7 +187,6 @@ bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner, void *value,
                bool swap_uptrs, gfp_t gfp_flags);
 
 void bpf_selem_free(struct bpf_local_storage_elem *selem,
-                   struct bpf_local_storage_map *smap,
                    bool reuse_now);
 
 int
index 400bdf8a3eb216af461c7892cb3b2b22faa0cb5f..95a5ea618cc57c14387bbf7ae0aab20b13f706a5 100644 (file)
@@ -97,6 +97,8 @@ bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner,
        }
 
        if (selem) {
+               RCU_INIT_POINTER(SDATA(selem)->smap, smap);
+
                if (value) {
                        /* No need to call check_and_init_map_value as memory is zero init */
                        copy_map_value(&smap->map, SDATA(selem)->data, value);
@@ -227,9 +229,12 @@ static void bpf_selem_free_trace_rcu(struct rcu_head *rcu)
 }
 
 void bpf_selem_free(struct bpf_local_storage_elem *selem,
-                   struct bpf_local_storage_map *smap,
                    bool reuse_now)
 {
+       struct bpf_local_storage_map *smap;
+
+       smap = rcu_dereference_check(SDATA(selem)->smap, bpf_rcu_lock_held());
+
        if (!smap->bpf_ma) {
                /* Only task storage has uptrs and task storage
                 * has moved to bpf_mem_alloc. Meaning smap->bpf_ma == true
@@ -263,7 +268,6 @@ void bpf_selem_free(struct bpf_local_storage_elem *selem,
 static void bpf_selem_free_list(struct hlist_head *list, bool reuse_now)
 {
        struct bpf_local_storage_elem *selem;
-       struct bpf_local_storage_map *smap;
        struct hlist_node *n;
 
        /* The "_safe" iteration is needed.
@@ -271,10 +275,8 @@ static void bpf_selem_free_list(struct hlist_head *list, bool reuse_now)
         * but bpf_selem_free will use the selem->rcu_head
         * which is union-ized with the selem->free_node.
         */
-       hlist_for_each_entry_safe(selem, n, list, free_node) {
-               smap = rcu_dereference_check(SDATA(selem)->smap, bpf_rcu_lock_held());
-               bpf_selem_free(selem, smap, reuse_now);
-       }
+       hlist_for_each_entry_safe(selem, n, list, free_node)
+               bpf_selem_free(selem, reuse_now);
 }
 
 /* local_storage->lock must be held and selem->local_storage == local_storage.
@@ -432,7 +434,6 @@ void bpf_selem_link_map(struct bpf_local_storage_map *smap,
        unsigned long flags;
 
        raw_spin_lock_irqsave(&b->lock, flags);
-       RCU_INIT_POINTER(SDATA(selem)->smap, smap);
        hlist_add_head_rcu(&selem->map_node, &b->list);
        raw_spin_unlock_irqrestore(&b->lock, flags);
 }
@@ -586,7 +587,7 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap,
 
                err = bpf_local_storage_alloc(owner, smap, selem, gfp_flags);
                if (err) {
-                       bpf_selem_free(selem, smap, true);
+                       bpf_selem_free(selem, true);
                        mem_uncharge(smap, owner, smap->elem_size);
                        return ERR_PTR(err);
                }
@@ -662,7 +663,7 @@ unlock:
        bpf_selem_free_list(&old_selem_free_list, false);
        if (alloc_selem) {
                mem_uncharge(smap, owner, smap->elem_size);
-               bpf_selem_free(alloc_selem, smap, true);
+               bpf_selem_free(alloc_selem, true);
        }
        return err ? ERR_PTR(err) : SDATA(selem);
 }
index bd3c686edc0b43ea52701bfed192630cd04c9f57..850dd736ccd12504fb8982f84d304cc04ef1be86 100644 (file)
@@ -196,7 +196,7 @@ int bpf_sk_storage_clone(const struct sock *sk, struct sock *newsk)
                } else {
                        ret = bpf_local_storage_alloc(newsk, smap, copy_selem, GFP_ATOMIC);
                        if (ret) {
-                               bpf_selem_free(copy_selem, smap, true);
+                               bpf_selem_free(copy_selem, true);
                                atomic_sub(smap->elem_size,
                                           &newsk->sk_omem_alloc);
                                bpf_map_put(map);