@@ -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+
897912static 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