@@ -31,7 +31,7 @@ struct bpf_struct_ops_map {
31
31
* (in kvalue.data).
32
32
*/
33
33
struct bpf_link * * links ;
34
- u32 links_cnt ;
34
+ u32 funcs_cnt ;
35
35
u32 image_pages_cnt ;
36
36
/* image_pages is an array of pages that has all the trampolines
37
37
* 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)
480
480
{
481
481
u32 i ;
482
482
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 ;
488
488
}
489
489
}
490
490
@@ -600,6 +600,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
600
600
int prog_fd , err ;
601
601
u32 i , trampoline_start , image_off = 0 ;
602
602
void * cur_image = NULL , * image = NULL ;
603
+ struct bpf_link * * plink ;
603
604
604
605
if (flags )
605
606
return - EINVAL ;
@@ -638,6 +639,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
638
639
udata = & uvalue -> data ;
639
640
kdata = & kvalue -> data ;
640
641
642
+ plink = st_map -> links ;
641
643
module_type = btf_type_by_id (btf_vmlinux , st_ops_ids [IDX_MODULE_ID ]);
642
644
for_each_member (i , t , member ) {
643
645
const struct btf_type * mtype , * ptype ;
@@ -713,7 +715,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
713
715
}
714
716
bpf_link_init (& link -> link , BPF_LINK_TYPE_STRUCT_OPS ,
715
717
& bpf_struct_ops_link_lops , prog );
716
- st_map -> links [ i ] = & link -> link ;
718
+ * plink ++ = & link -> link ;
717
719
718
720
trampoline_start = image_off ;
719
721
err = bpf_struct_ops_prepare_trampoline (tlinks , link ,
@@ -894,6 +896,19 @@ static int bpf_struct_ops_map_alloc_check(union bpf_attr *attr)
894
896
return 0 ;
895
897
}
896
898
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
+
897
912
static struct bpf_map * bpf_struct_ops_map_alloc (union bpf_attr * attr )
898
913
{
899
914
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)
960
975
map = & st_map -> map ;
961
976
962
977
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 );
964
979
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 * ),
966
981
NUMA_NO_NODE );
967
982
if (!st_map -> uvalue || !st_map -> links ) {
968
983
ret = - ENOMEM ;
@@ -993,7 +1008,7 @@ static u64 bpf_struct_ops_map_mem_usage(const struct bpf_map *map)
993
1008
usage = sizeof (* st_map ) +
994
1009
vt -> size - sizeof (struct bpf_struct_ops_value );
995
1010
usage += vt -> size ;
996
- usage += btf_type_vlen ( vt ) * sizeof (struct bpf_links * );
1011
+ usage += st_map -> funcs_cnt * sizeof (struct bpf_link * );
997
1012
usage += PAGE_SIZE ;
998
1013
return usage ;
999
1014
}
0 commit comments