Commit e76a33e1 authored by Amery Hung's avatar Amery Hung Committed by Alexei Starovoitov
Browse files

bpf: Remove smap argument from bpf_selem_free()



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: default avatarAmery Hung <ameryhung@gmail.com>
Reviewed-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20251114201329.3275875-3-ameryhung@gmail.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 0e854e55
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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
+10 −9
Original line number Diff line number Diff line
@@ -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 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap,
	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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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);