On Wed, Apr 20, 2022 at 1:17 PM Kui-Feng Lee <kuifeng@xxxxxx> wrote: > > On Wed, 2022-04-20 at 10:37 -0700, Andrii Nakryiko wrote: > > On Fri, Apr 15, 2022 at 9:30 PM Kui-Feng Lee <kuifeng@xxxxxx> wrote: > > > > > > Replace struct bpf_tramp_progs with struct bpf_tramp_links to > > > collect > > > struct bpf_tramp_link(s) for a trampoline. struct bpf_tramp_link > > > extends bpf_link to act as a linked list node. > > > > > > arch_prepare_bpf_trampoline() accepts a struct bpf_tramp_links to > > > collects all bpf_tramp_link(s) that a trampoline should call. > > > > > > Change BPF trampoline and bpf_struct_ops to pass bpf_tramp_links > > > instead of bpf_tramp_progs. > > > > > > Signed-off-by: Kui-Feng Lee <kuifeng@xxxxxx> > > > --- > > > arch/x86/net/bpf_jit_comp.c | 36 +++++++++-------- > > > include/linux/bpf.h | 36 +++++++++++------ > > > include/linux/bpf_types.h | 1 + > > > include/uapi/linux/bpf.h | 1 + > > > kernel/bpf/bpf_struct_ops.c | 69 ++++++++++++++++++++++-------- > > > -- > > > kernel/bpf/syscall.c | 23 ++++------- > > > kernel/bpf/trampoline.c | 73 +++++++++++++++++++----------- > > > ---- > > > net/bpf/bpf_dummy_struct_ops.c | 37 ++++++++++++++--- > > > tools/bpf/bpftool/link.c | 1 + > > > tools/include/uapi/linux/bpf.h | 1 + > > > 10 files changed, 175 insertions(+), 103 deletions(-) > > > > > > > [...] > > > > > @@ -385,6 +399,7 @@ static int > > > bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, > > > for_each_member(i, t, member) { > > > const struct btf_type *mtype, *ptype; > > > struct bpf_prog *prog; > > > + struct bpf_tramp_link *link; > > > u32 moff; > > > > > > moff = __btf_member_bit_offset(t, member) / 8; > > > @@ -438,16 +453,26 @@ static int > > > bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, > > > err = PTR_ERR(prog); > > > goto reset_unlock; > > > } > > > - st_map->progs[i] = prog; > > > > > > if (prog->type != BPF_PROG_TYPE_STRUCT_OPS || > > > prog->aux->attach_btf_id != st_ops->type_id || > > > prog->expected_attach_type != i) { > > > + bpf_prog_put(prog); > > > err = -EINVAL; > > > goto reset_unlock; > > > } > > > > > > - err = bpf_struct_ops_prepare_trampoline(tprogs, > > > prog, > > > + link = kzalloc(sizeof(*link), GFP_USER); > > > > seems like you are leaking this link and all the links allocated in > > previous successful iterations of this loop? > > In the block of reset_unlok, it calls bpf_struct_ops_map_put_progs() to > release all links in st_map including all links of previous iterations. > > > > > > + if (!link) { > > > + bpf_prog_put(prog); > > > + err = -ENOMEM; > > > + goto reset_unlock; > > > + } > > > + bpf_link_init(&link->link, > > > BPF_LINK_TYPE_STRUCT_OPS, > > > + &bpf_struct_ops_link_lops, prog); > > > + st_map->links[i] = &link->link; > > > + > > > + err = bpf_struct_ops_prepare_trampoline(tlinks, > > > link, > > > &st_ops- > > > >func_models[i], > > > image, > > > image_end); > > > if (err < 0) > > > @@ -490,7 +515,7 @@ static int > > > bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, > > > memset(uvalue, 0, map->value_size); > > > memset(kvalue, 0, map->value_size); > > > unlock: > > > - kfree(tprogs); > > > + kfree(tlinks); > > > > so you'll need to free those links inside tlinks (or wherever else > > they are stored) > > All links are in st_maps. > They will be free by bpf_struct_ops_map_put_progs(). > Does that make sense? ah, yeah, makes sense. I was wondering how did we miss this in previous revisions. Great, never mind this issue then. > > > > > > mutex_unlock(&st_map->lock); > > > return err; > > > } [...]