mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:04:51 +01:00
bpf: Convert bpf_selem_unlink to failable
To prepare changing both bpf_local_storage_map_bucket::lock and bpf_local_storage::lock to rqspinlock, convert bpf_selem_unlink() to failable. It still always succeeds and returns 0 until the change happens. No functional change. Open code bpf_selem_unlink_storage() in the only caller, bpf_selem_unlink(), since unlink_map and unlink_storage must be done together after all the necessary locks are acquired. For bpf_local_storage_map_free(), ignore the return from bpf_selem_unlink() for now. A later patch will allow it to unlink selems even when failing to acquire locks. 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-5-ameryhung@gmail.com
This commit is contained in:
parent
fd103ffc57
commit
403e935f91
6 changed files with 39 additions and 49 deletions
|
|
@ -176,7 +176,7 @@ int bpf_local_storage_map_check_btf(const struct bpf_map *map,
|
|||
void bpf_selem_link_storage_nolock(struct bpf_local_storage *local_storage,
|
||||
struct bpf_local_storage_elem *selem);
|
||||
|
||||
void bpf_selem_unlink(struct bpf_local_storage_elem *selem, bool reuse_now);
|
||||
int bpf_selem_unlink(struct bpf_local_storage_elem *selem, bool reuse_now);
|
||||
|
||||
int bpf_selem_link_map(struct bpf_local_storage_map *smap,
|
||||
struct bpf_local_storage *local_storage,
|
||||
|
|
|
|||
|
|
@ -118,8 +118,7 @@ static int cgroup_storage_delete(struct cgroup *cgroup, struct bpf_map *map)
|
|||
if (!sdata)
|
||||
return -ENOENT;
|
||||
|
||||
bpf_selem_unlink(SELEM(sdata), false);
|
||||
return 0;
|
||||
return bpf_selem_unlink(SELEM(sdata), false);
|
||||
}
|
||||
|
||||
static long bpf_cgrp_storage_delete_elem(struct bpf_map *map, void *key)
|
||||
|
|
|
|||
|
|
@ -110,9 +110,7 @@ static int inode_storage_delete(struct inode *inode, struct bpf_map *map)
|
|||
if (!sdata)
|
||||
return -ENOENT;
|
||||
|
||||
bpf_selem_unlink(SELEM(sdata), false);
|
||||
|
||||
return 0;
|
||||
return bpf_selem_unlink(SELEM(sdata), false);
|
||||
}
|
||||
|
||||
static long bpf_fd_inode_storage_delete_elem(struct bpf_map *map, void *key)
|
||||
|
|
|
|||
|
|
@ -308,33 +308,6 @@ static bool bpf_selem_unlink_storage_nolock(struct bpf_local_storage *local_stor
|
|||
return free_local_storage;
|
||||
}
|
||||
|
||||
static void bpf_selem_unlink_storage(struct bpf_local_storage_elem *selem,
|
||||
bool reuse_now)
|
||||
{
|
||||
struct bpf_local_storage *local_storage;
|
||||
bool free_local_storage = false;
|
||||
HLIST_HEAD(selem_free_list);
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely(!selem_linked_to_storage_lockless(selem)))
|
||||
/* selem has already been unlinked from sk */
|
||||
return;
|
||||
|
||||
local_storage = rcu_dereference_check(selem->local_storage,
|
||||
bpf_rcu_lock_held());
|
||||
|
||||
raw_spin_lock_irqsave(&local_storage->lock, flags);
|
||||
if (likely(selem_linked_to_storage(selem)))
|
||||
free_local_storage = bpf_selem_unlink_storage_nolock(
|
||||
local_storage, selem, &selem_free_list);
|
||||
raw_spin_unlock_irqrestore(&local_storage->lock, flags);
|
||||
|
||||
bpf_selem_free_list(&selem_free_list, reuse_now);
|
||||
|
||||
if (free_local_storage)
|
||||
bpf_local_storage_free(local_storage, reuse_now);
|
||||
}
|
||||
|
||||
void bpf_selem_link_storage_nolock(struct bpf_local_storage *local_storage,
|
||||
struct bpf_local_storage_elem *selem)
|
||||
{
|
||||
|
|
@ -386,19 +359,43 @@ static void bpf_selem_link_map_nolock(struct bpf_local_storage_map_bucket *b,
|
|||
hlist_add_head_rcu(&selem->map_node, &b->list);
|
||||
}
|
||||
|
||||
void bpf_selem_unlink(struct bpf_local_storage_elem *selem, bool reuse_now)
|
||||
int bpf_selem_unlink(struct bpf_local_storage_elem *selem, bool reuse_now)
|
||||
{
|
||||
int err;
|
||||
struct bpf_local_storage *local_storage;
|
||||
bool free_local_storage = false;
|
||||
HLIST_HEAD(selem_free_list);
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
/* Always unlink from map before unlinking from local_storage
|
||||
* because selem will be freed after successfully unlinked from
|
||||
* the local_storage.
|
||||
*/
|
||||
err = bpf_selem_unlink_map(selem);
|
||||
if (err)
|
||||
return;
|
||||
if (unlikely(!selem_linked_to_storage_lockless(selem)))
|
||||
/* selem has already been unlinked from sk */
|
||||
return 0;
|
||||
|
||||
bpf_selem_unlink_storage(selem, reuse_now);
|
||||
local_storage = rcu_dereference_check(selem->local_storage,
|
||||
bpf_rcu_lock_held());
|
||||
|
||||
raw_spin_lock_irqsave(&local_storage->lock, flags);
|
||||
if (likely(selem_linked_to_storage(selem))) {
|
||||
/* Always unlink from map before unlinking from local_storage
|
||||
* because selem will be freed after successfully unlinked from
|
||||
* the local_storage.
|
||||
*/
|
||||
err = bpf_selem_unlink_map(selem);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
free_local_storage = bpf_selem_unlink_storage_nolock(
|
||||
local_storage, selem, &selem_free_list);
|
||||
}
|
||||
out:
|
||||
raw_spin_unlock_irqrestore(&local_storage->lock, flags);
|
||||
|
||||
bpf_selem_free_list(&selem_free_list, reuse_now);
|
||||
|
||||
if (free_local_storage)
|
||||
bpf_local_storage_free(local_storage, reuse_now);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void __bpf_local_storage_insert_cache(struct bpf_local_storage *local_storage,
|
||||
|
|
|
|||
|
|
@ -167,9 +167,7 @@ static int task_storage_delete(struct task_struct *task, struct bpf_map *map,
|
|||
if (!nobusy)
|
||||
return -EBUSY;
|
||||
|
||||
bpf_selem_unlink(SELEM(sdata), false);
|
||||
|
||||
return 0;
|
||||
return bpf_selem_unlink(SELEM(sdata), false);
|
||||
}
|
||||
|
||||
static long bpf_pid_task_storage_delete_elem(struct bpf_map *map, void *key)
|
||||
|
|
|
|||
|
|
@ -40,9 +40,7 @@ static int bpf_sk_storage_del(struct sock *sk, struct bpf_map *map)
|
|||
if (!sdata)
|
||||
return -ENOENT;
|
||||
|
||||
bpf_selem_unlink(SELEM(sdata), false);
|
||||
|
||||
return 0;
|
||||
return bpf_selem_unlink(SELEM(sdata), false);
|
||||
}
|
||||
|
||||
/* Called by __sk_destruct() & bpf_sk_storage_clone() */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue