On Thu, Aug 26, 2021 at 12:41 PM Jiri Olsa <jolsa@xxxxxxxxxx> wrote: > > Adding new multi trampoline link (BPF_LINK_TYPE_TRACING_MULTI) > as an interface to attach program to multiple functions. > > The link_create bpf_attr interface already has 'bpf_prog' file > descriptor, that defines the program to be attached. It must be > loaded with BPF_F_MULTI_FUNC flag. > > Adding new multi_btf_ids/multi_btf_ids_cnt link_create bpf_attr > fields that provides BTF ids. > > The new link gets multi trampoline (via bpf_trampoline_multi_get) > and links the provided program with embedded trampolines and the > 'main' trampoline with new multi link/unlink functions: > > int bpf_trampoline_multi_link_prog(struct bpf_prog *prog, > struct bpf_trampoline_multi *tr); > int bpf_trampoline_multi_unlink_prog(struct bpf_prog *prog, > struct bpf_trampoline_multi *tr); > > If embedded trampoline contains fexit programs, we need to switch > its model to the multi trampoline model (because of the final 'ret' > argument). We keep the count of attached multi func programs for each > trampoline, so we can tell when to switch the model. > > Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx> > --- > include/linux/bpf.h | 5 ++ > include/uapi/linux/bpf.h | 5 ++ > kernel/bpf/core.c | 1 + > kernel/bpf/syscall.c | 120 +++++++++++++++++++++++++++++++++ > kernel/bpf/trampoline.c | 87 ++++++++++++++++++++++-- > tools/include/uapi/linux/bpf.h | 5 ++ > 6 files changed, 219 insertions(+), 4 deletions(-) > [...] > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index 1f9d336861f0..9533200ffadf 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -1008,6 +1008,7 @@ enum bpf_link_type { > BPF_LINK_TYPE_NETNS = 5, > BPF_LINK_TYPE_XDP = 6, > BPF_LINK_TYPE_PERF_EVENT = 7, > + BPF_LINK_TYPE_TRACING_MULTI = 8, > > MAX_BPF_LINK_TYPE, > }; > @@ -1462,6 +1463,10 @@ union bpf_attr { > */ > __u64 bpf_cookie; > } perf_event; > + struct { > + __aligned_u64 multi_btf_ids; /* addresses to attach */ > + __u32 multi_btf_ids_cnt; /* addresses count */ > + }; Please follow the pattern of perf_event, name this struct "multi". > }; > } link_create; > > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c > index bad03dde97a2..6c16ac43dd91 100644 > --- a/kernel/bpf/core.c > +++ b/kernel/bpf/core.c [...] > + > + bpf_link_init(&link->link, BPF_LINK_TYPE_TRACING_MULTI, > + &bpf_tracing_multi_link_lops, prog); > + link->attach_type = prog->expected_attach_type; > + link->multi = multi; > + > + err = bpf_link_prime(&link->link, &link_primer); > + if (err) > + goto out_free; > + err = bpf_trampoline_multi_link_prog(prog, multi); > + if (err) > + goto out_free; bpf_link_cleanup(), can't free link after priming. Look at other places using bpf_link. > + return bpf_link_settle(&link_primer); > + > +out_free: > + bpf_trampoline_multi_put(multi); > + kfree(link); > +out_free_ids: > + kfree(btf_ids); > + return err; > +} > + [...]