mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2026-01-07 02:09:20 +00:00
bpf: Use function pointers count as struct_ops links count
Only function pointers in a struct_ops structure can be linked to bpf progs, so set the links count to the function pointers count, instead of the total members count in the structure. Suggested-by: Martin KaFai Lau <martin.lau@linux.dev> Signed-off-by: Xu Kuohai <xukuohai@huawei.com> Link: https://lore.kernel.org/r/20241112145849.3436772-3-xukuohai@huaweicloud.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
bd9d9b48eb
commit
821a3fa32b
@ -31,7 +31,7 @@ struct bpf_struct_ops_map {
|
||||
* (in kvalue.data).
|
||||
*/
|
||||
struct bpf_link **links;
|
||||
u32 links_cnt;
|
||||
u32 funcs_cnt;
|
||||
u32 image_pages_cnt;
|
||||
/* image_pages is an array of pages that has all the trampolines
|
||||
* that stores the func args before calling the bpf_prog.
|
||||
@ -480,11 +480,11 @@ static void bpf_struct_ops_map_put_progs(struct bpf_struct_ops_map *st_map)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < st_map->links_cnt; i++) {
|
||||
if (st_map->links[i]) {
|
||||
bpf_link_put(st_map->links[i]);
|
||||
st_map->links[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < st_map->funcs_cnt; i++) {
|
||||
if (!st_map->links[i])
|
||||
break;
|
||||
bpf_link_put(st_map->links[i]);
|
||||
st_map->links[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -600,6 +600,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
|
||||
int prog_fd, err;
|
||||
u32 i, trampoline_start, image_off = 0;
|
||||
void *cur_image = NULL, *image = NULL;
|
||||
struct bpf_link **plink;
|
||||
|
||||
if (flags)
|
||||
return -EINVAL;
|
||||
@ -638,6 +639,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
|
||||
udata = &uvalue->data;
|
||||
kdata = &kvalue->data;
|
||||
|
||||
plink = st_map->links;
|
||||
module_type = btf_type_by_id(btf_vmlinux, st_ops_ids[IDX_MODULE_ID]);
|
||||
for_each_member(i, t, member) {
|
||||
const struct btf_type *mtype, *ptype;
|
||||
@ -713,7 +715,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
|
||||
}
|
||||
bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS,
|
||||
&bpf_struct_ops_link_lops, prog);
|
||||
st_map->links[i] = &link->link;
|
||||
*plink++ = &link->link;
|
||||
|
||||
trampoline_start = image_off;
|
||||
err = bpf_struct_ops_prepare_trampoline(tlinks, link,
|
||||
@ -894,6 +896,19 @@ static int bpf_struct_ops_map_alloc_check(union bpf_attr *attr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 count_func_ptrs(const struct btf *btf, const struct btf_type *t)
|
||||
{
|
||||
int i;
|
||||
u32 count;
|
||||
const struct btf_member *member;
|
||||
|
||||
count = 0;
|
||||
for_each_member(i, t, member)
|
||||
if (btf_type_resolve_func_ptr(btf, member->type, NULL))
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
|
||||
{
|
||||
const struct bpf_struct_ops_desc *st_ops_desc;
|
||||
@ -960,9 +975,9 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
|
||||
map = &st_map->map;
|
||||
|
||||
st_map->uvalue = bpf_map_area_alloc(vt->size, NUMA_NO_NODE);
|
||||
st_map->links_cnt = btf_type_vlen(t);
|
||||
st_map->funcs_cnt = count_func_ptrs(btf, t);
|
||||
st_map->links =
|
||||
bpf_map_area_alloc(st_map->links_cnt * sizeof(struct bpf_links *),
|
||||
bpf_map_area_alloc(st_map->funcs_cnt * sizeof(struct bpf_link *),
|
||||
NUMA_NO_NODE);
|
||||
if (!st_map->uvalue || !st_map->links) {
|
||||
ret = -ENOMEM;
|
||||
@ -993,7 +1008,7 @@ static u64 bpf_struct_ops_map_mem_usage(const struct bpf_map *map)
|
||||
usage = sizeof(*st_map) +
|
||||
vt->size - sizeof(struct bpf_struct_ops_value);
|
||||
usage += vt->size;
|
||||
usage += btf_type_vlen(vt) * sizeof(struct bpf_links *);
|
||||
usage += st_map->funcs_cnt * sizeof(struct bpf_link *);
|
||||
usage += PAGE_SIZE;
|
||||
return usage;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user