mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
bpf: Remove __rcu tagging in st_link->map
st_link->map is always written under update_mutex. The paths that read st_link->map with rcu_read_lock() are not in the fast path, so they can simply take update_mutex instead. Remove the __rcu annotation and replace all RCU accessors with direct pointer reads under update_mutex. Use READ_ONCE() in bpf_struct_ops_map_link_poll() which reads the pointer without holding update_mutex. It is a simplification change. Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Signed-off-by: Amery Hung <ameryhung@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260917200542.3689605-2-ameryhung@gmail.com
This commit is contained in:
parent
72a930db88
commit
0120895121
|
|
@ -57,7 +57,7 @@ struct bpf_struct_ops_map {
|
|||
|
||||
struct bpf_struct_ops_link {
|
||||
struct bpf_link link;
|
||||
struct bpf_map __rcu *map;
|
||||
struct bpf_map *map;
|
||||
wait_queue_head_t wait_hup;
|
||||
};
|
||||
|
||||
|
|
@ -1297,8 +1297,7 @@ static void bpf_struct_ops_map_link_dealloc(struct bpf_link *link)
|
|||
struct bpf_struct_ops_map *st_map;
|
||||
|
||||
st_link = container_of(link, struct bpf_struct_ops_link, link);
|
||||
st_map = (struct bpf_struct_ops_map *)
|
||||
rcu_dereference_protected(st_link->map, true);
|
||||
st_map = (struct bpf_struct_ops_map *)st_link->map;
|
||||
if (st_map) {
|
||||
st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data, link);
|
||||
bpf_map_put(&st_map->map);
|
||||
|
|
@ -1313,11 +1312,11 @@ static void bpf_struct_ops_map_link_show_fdinfo(const struct bpf_link *link,
|
|||
struct bpf_map *map;
|
||||
|
||||
st_link = container_of(link, struct bpf_struct_ops_link, link);
|
||||
rcu_read_lock();
|
||||
map = rcu_dereference(st_link->map);
|
||||
mutex_lock(&update_mutex);
|
||||
map = st_link->map;
|
||||
if (map)
|
||||
seq_printf(seq, "map_id:\t%d\n", map->id);
|
||||
rcu_read_unlock();
|
||||
mutex_unlock(&update_mutex);
|
||||
}
|
||||
|
||||
static int bpf_struct_ops_map_link_fill_link_info(const struct bpf_link *link,
|
||||
|
|
@ -1327,11 +1326,11 @@ static int bpf_struct_ops_map_link_fill_link_info(const struct bpf_link *link,
|
|||
struct bpf_map *map;
|
||||
|
||||
st_link = container_of(link, struct bpf_struct_ops_link, link);
|
||||
rcu_read_lock();
|
||||
map = rcu_dereference(st_link->map);
|
||||
mutex_lock(&update_mutex);
|
||||
map = st_link->map;
|
||||
if (map)
|
||||
info->struct_ops.map_id = map->id;
|
||||
rcu_read_unlock();
|
||||
mutex_unlock(&update_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1354,7 +1353,7 @@ static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map
|
|||
|
||||
mutex_lock(&update_mutex);
|
||||
|
||||
old_map = rcu_dereference_protected(st_link->map, lockdep_is_held(&update_mutex));
|
||||
old_map = st_link->map;
|
||||
if (!old_map) {
|
||||
err = -ENOLINK;
|
||||
goto err_out;
|
||||
|
|
@ -1376,7 +1375,7 @@ static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map
|
|||
goto err_out;
|
||||
|
||||
bpf_map_inc(new_map);
|
||||
rcu_assign_pointer(st_link->map, new_map);
|
||||
WRITE_ONCE(st_link->map, new_map);
|
||||
bpf_map_put(old_map);
|
||||
|
||||
err_out:
|
||||
|
|
@ -1393,7 +1392,7 @@ static int bpf_struct_ops_map_link_detach(struct bpf_link *link)
|
|||
|
||||
mutex_lock(&update_mutex);
|
||||
|
||||
map = rcu_dereference_protected(st_link->map, lockdep_is_held(&update_mutex));
|
||||
map = st_link->map;
|
||||
if (!map) {
|
||||
mutex_unlock(&update_mutex);
|
||||
return 0;
|
||||
|
|
@ -1402,7 +1401,7 @@ static int bpf_struct_ops_map_link_detach(struct bpf_link *link)
|
|||
|
||||
st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data, link);
|
||||
|
||||
RCU_INIT_POINTER(st_link->map, NULL);
|
||||
WRITE_ONCE(st_link->map, NULL);
|
||||
/* Pair with bpf_map_get() in bpf_struct_ops_link_create() or
|
||||
* bpf_map_inc() in bpf_struct_ops_map_link_update().
|
||||
*/
|
||||
|
|
@ -1422,7 +1421,7 @@ static __poll_t bpf_struct_ops_map_link_poll(struct file *file,
|
|||
|
||||
poll_wait(file, &st_link->wait_hup, pts);
|
||||
|
||||
return rcu_access_pointer(st_link->map) ? 0 : EPOLLHUP;
|
||||
return READ_ONCE(st_link->map) ? 0 : EPOLLHUP;
|
||||
}
|
||||
|
||||
static const struct bpf_link_ops bpf_struct_ops_map_lops = {
|
||||
|
|
@ -1478,7 +1477,7 @@ int bpf_struct_ops_link_create(union bpf_attr *attr)
|
|||
link = NULL;
|
||||
goto err_out;
|
||||
}
|
||||
RCU_INIT_POINTER(link->map, map);
|
||||
link->map = map;
|
||||
mutex_unlock(&update_mutex);
|
||||
|
||||
return bpf_link_settle(&link_primer);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user