Skip to content

Commit 821a3fa

Browse files
Xu KuohaiAlexei Starovoitov
authored andcommitted
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 <[email protected]> Signed-off-by: Xu Kuohai <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent bd9d9b4 commit 821a3fa

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

kernel/bpf/bpf_struct_ops.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct bpf_struct_ops_map {
3131
* (in kvalue.data).
3232
*/
3333
struct bpf_link **links;
34-
u32 links_cnt;
34+
u32 funcs_cnt;
3535
u32 image_pages_cnt;
3636
/* image_pages is an array of pages that has all the trampolines
3737
* 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)
480480
{
481481
u32 i;
482482

483-
for (i = 0; i < st_map->links_cnt; i++) {
484-
if (st_map->links[i]) {
485-
bpf_link_put(st_map->links[i]);
486-
st_map->links[i] = NULL;
487-
}
483+
for (i = 0; i < st_map->funcs_cnt; i++) {
484+
if (!st_map->links[i])
485+
break;
486+
bpf_link_put(st_map->links[i]);
487+
st_map->links[i] = NULL;
488488
}
489489
}
490490

@@ -600,6 +600,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
600600
int prog_fd, err;
601601
u32 i, trampoline_start, image_off = 0;
602602
void *cur_image = NULL, *image = NULL;
603+
struct bpf_link **plink;
603604

604605
if (flags)
605606
return -EINVAL;
@@ -638,6 +639,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
638639
udata = &uvalue->data;
639640
kdata = &kvalue->data;
640641

642+
plink = st_map->links;
641643
module_type = btf_type_by_id(btf_vmlinux, st_ops_ids[IDX_MODULE_ID]);
642644
for_each_member(i, t, member) {
643645
const struct btf_type *mtype, *ptype;
@@ -713,7 +715,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
713715
}
714716
bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS,
715717
&bpf_struct_ops_link_lops, prog);
716-
st_map->links[i] = &link->link;
718+
*plink++ = &link->link;
717719

718720
trampoline_start = image_off;
719721
err = bpf_struct_ops_prepare_trampoline(tlinks, link,
@@ -894,6 +896,19 @@ static int bpf_struct_ops_map_alloc_check(union bpf_attr *attr)
894896
return 0;
895897
}
896898

899+
static u32 count_func_ptrs(const struct btf *btf, const struct btf_type *t)
900+
{
901+
int i;
902+
u32 count;
903+
const struct btf_member *member;
904+
905+
count = 0;
906+
for_each_member(i, t, member)
907+
if (btf_type_resolve_func_ptr(btf, member->type, NULL))
908+
count++;
909+
return count;
910+
}
911+
897912
static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
898913
{
899914
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)
960975
map = &st_map->map;
961976

962977
st_map->uvalue = bpf_map_area_alloc(vt->size, NUMA_NO_NODE);
963-
st_map->links_cnt = btf_type_vlen(t);
978+
st_map->funcs_cnt = count_func_ptrs(btf, t);
964979
st_map->links =
965-
bpf_map_area_alloc(st_map->links_cnt * sizeof(struct bpf_links *),
980+
bpf_map_area_alloc(st_map->funcs_cnt * sizeof(struct bpf_link *),
966981
NUMA_NO_NODE);
967982
if (!st_map->uvalue || !st_map->links) {
968983
ret = -ENOMEM;
@@ -993,7 +1008,7 @@ static u64 bpf_struct_ops_map_mem_usage(const struct bpf_map *map)
9931008
usage = sizeof(*st_map) +
9941009
vt->size - sizeof(struct bpf_struct_ops_value);
9951010
usage += vt->size;
996-
usage += btf_type_vlen(vt) * sizeof(struct bpf_links *);
1011+
usage += st_map->funcs_cnt * sizeof(struct bpf_link *);
9971012
usage += PAGE_SIZE;
9981013
return usage;
9991014
}

0 commit comments

Comments
 (0)