On Tue, Apr 30, 2024 at 4:29 AM Jiri Olsa <jolsa@xxxxxxxxxx> wrote: > > Adding support to attach program in kprobe session mode > with bpf_program__attach_kprobe_multi_opts function. > > Adding session bool to bpf_kprobe_multi_opts struct that allows > to load and attach the bpf program via kprobe session. > the attachment to create kprobe multi session. > > Also adding new program loader section that allows: > SEC("kprobe.session/bpf_fentry_test*") > > and loads/attaches kprobe program as kprobe session. > > Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx> > --- > tools/lib/bpf/bpf.c | 1 + > tools/lib/bpf/libbpf.c | 39 +++++++++++++++++++++++++++++++++++++-- > tools/lib/bpf/libbpf.h | 4 +++- > 3 files changed, 41 insertions(+), 3 deletions(-) > > diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c > index c9f4e04f38fe..466a29d80124 100644 > --- a/tools/lib/bpf/bpf.c > +++ b/tools/lib/bpf/bpf.c > @@ -766,6 +766,7 @@ int bpf_link_create(int prog_fd, int target_fd, > return libbpf_err(-EINVAL); > break; > case BPF_TRACE_KPROBE_MULTI: > + case BPF_TRACE_KPROBE_SESSION: > attr.link_create.kprobe_multi.flags = OPTS_GET(opts, kprobe_multi.flags, 0); > attr.link_create.kprobe_multi.cnt = OPTS_GET(opts, kprobe_multi.cnt, 0); > attr.link_create.kprobe_multi.syms = ptr_to_u64(OPTS_GET(opts, kprobe_multi.syms, 0)); > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index 898d5d34ecea..16dae279a900 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -9273,6 +9273,7 @@ static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_lin > static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link); > static int attach_trace(const struct bpf_program *prog, long cookie, struct bpf_link **link); > static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link); > +static int attach_kprobe_session(const struct bpf_program *prog, long cookie, struct bpf_link **link); > static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link); > static int attach_lsm(const struct bpf_program *prog, long cookie, struct bpf_link **link); > static int attach_iter(const struct bpf_program *prog, long cookie, struct bpf_link **link); > @@ -9289,6 +9290,7 @@ static const struct bpf_sec_def section_defs[] = { > SEC_DEF("uretprobe.s+", KPROBE, 0, SEC_SLEEPABLE, attach_uprobe), > SEC_DEF("kprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi), > SEC_DEF("kretprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi), > + SEC_DEF("kprobe.session+", KPROBE, BPF_TRACE_KPROBE_SESSION, SEC_NONE, attach_kprobe_session), > SEC_DEF("uprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi), > SEC_DEF("uretprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi), > SEC_DEF("uprobe.multi.s+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_SLEEPABLE, attach_uprobe_multi), > @@ -11381,13 +11383,14 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog, > struct kprobe_multi_resolve res = { > .pattern = pattern, > }; > + enum bpf_attach_type attach_type; > struct bpf_link *link = NULL; > char errmsg[STRERR_BUFSIZE]; > const unsigned long *addrs; > int err, link_fd, prog_fd; > + bool retprobe, session; > const __u64 *cookies; > const char **syms; > - bool retprobe; > size_t cnt; > > if (!OPTS_VALID(opts, bpf_kprobe_multi_opts)) > @@ -11426,6 +11429,12 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog, > } > > retprobe = OPTS_GET(opts, retprobe, false); > + session = OPTS_GET(opts, session, false); > + > + if (retprobe && session) > + return libbpf_err_ptr(-EINVAL); > + > + attach_type = session ? BPF_TRACE_KPROBE_SESSION : BPF_TRACE_KPROBE_MULTI; > > lopts.kprobe_multi.syms = syms; > lopts.kprobe_multi.addrs = addrs; > @@ -11440,7 +11449,7 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog, > } > link->detach = &bpf_link__detach_fd; > > - link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, &lopts); > + link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts); > if (link_fd < 0) { > err = -errno; > pr_warn("prog '%s': failed to attach: %s\n", > @@ -11546,6 +11555,32 @@ static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, stru > return libbpf_get_error(*link); > } > > +static int attach_kprobe_session(const struct bpf_program *prog, long cookie, > + struct bpf_link **link) > +{ > + LIBBPF_OPTS(bpf_kprobe_multi_opts, opts, .session = true); > + const char *spec; > + char *pattern; > + int n; > + > + *link = NULL; > + > + /* no auto-attach for SEC("kprobe.session") */ > + if (strcmp(prog->sec_name, "kprobe.session") == 0) > + return 0; > + > + spec = prog->sec_name + sizeof("kprobe.session/") - 1; > + n = sscanf(spec, "%m[a-zA-Z0-9_.*?]", &pattern); > + if (n < 1) { > + pr_warn("kprobe session pattern is invalid: %s\n", pattern); this should be printing spec, not pattern, please send a follow up fix, thanks > + return -EINVAL; > + } > + > + *link = bpf_program__attach_kprobe_multi_opts(prog, pattern, &opts); > + free(pattern); > + return *link ? 0 : -errno; > +} > + > static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link) > { > char *probe_type = NULL, *binary_path = NULL, *func_name = NULL; > diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h > index 1333ae20ebe6..c3f77d9260fe 100644 > --- a/tools/lib/bpf/libbpf.h > +++ b/tools/lib/bpf/libbpf.h > @@ -539,10 +539,12 @@ struct bpf_kprobe_multi_opts { > size_t cnt; > /* create return kprobes */ > bool retprobe; > + /* create session kprobes */ > + bool session; > size_t :0; > }; > > -#define bpf_kprobe_multi_opts__last_field retprobe > +#define bpf_kprobe_multi_opts__last_field session > > LIBBPF_API struct bpf_link * > bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog, > -- > 2.44.0 >