On Sun, Mar 5, 2023 at 10:48 PM <menglong8.dong@xxxxxxxxx> wrote: > > From: Menglong Dong <imagedong@xxxxxxxxxxx> > > By default, libbpf will attach the kprobe/uprobe BPF program in the > latest mode that supported by kernel. In this patch, we add the support > to let users manually attach kprobe/uprobe in legacy or perf mode. > > There are 3 mode that supported by the kernel to attach kprobe/uprobe: > > LEGACY: create perf event in legacy way and don't use bpf_link > PERF: create perf event with perf_event_open() and don't use bpf_link > LINK: create perf event with perf_event_open() and use bpf_link > > Users now can manually choose the mode with > bpf_program__attach_uprobe_opts()/bpf_program__attach_kprobe_opts(). > > Link: https://lore.kernel.org/bpf/20230113093427.1666466-1-imagedong@xxxxxxxxxxx/ > Reviewed-by: Biao Jiang <benbjiang@xxxxxxxxxxx> > Signed-off-by: Menglong Dong <imagedong@xxxxxxxxxxx> > --- I fixed few small issues I pointed out below and applied to bpf-next. Thanks! > v4: > - rename eBPF to BPF in the doc > - use OPTS_GET() to get the value of 'force_ioctl_attach' > - error out on attach mode is not supported > v2: > - rename no_link to force_ioctl_attach > - rename probe_mode to probe_attach_mode > - add more doc for probe_attach_mode > - return -ENOTSUP when necessray in bpf_program__attach_uprobe_opts and > bpf_program__attach_kprobe_opts > --- > tools/lib/bpf/libbpf.c | 47 +++++++++++++++++++++++++++++++++++++++++- > tools/lib/bpf/libbpf.h | 31 +++++++++++++++++++++++++--- > 2 files changed, 74 insertions(+), 4 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index dacaae31b76a..77df4d275d22 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -9747,7 +9747,8 @@ struct bpf_link *bpf_program__attach_perf_event_opts(const struct bpf_program *p > link->link.dealloc = &bpf_link_perf_dealloc; > link->perf_event_fd = pfd; > > - if (kernel_supports(prog->obj, FEAT_PERF_LINK)) { > + if (kernel_supports(prog->obj, FEAT_PERF_LINK) && !OPTS_GET(opts, force_ioctl_attach, > + false)) { too ugly, I added local variable for OPTS_GET() result > DECLARE_LIBBPF_OPTS(bpf_link_create_opts, link_opts, > .perf_event.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0)); > > @@ -10106,6 +10107,7 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog, > const struct bpf_kprobe_opts *opts) > { > DECLARE_LIBBPF_OPTS(bpf_perf_event_opts, pe_opts); > + enum probe_attach_mode attach_mode; > char errmsg[STRERR_BUFSIZE]; > char *legacy_probe = NULL; > struct bpf_link *link; > @@ -10116,11 +10118,32 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog, > if (!OPTS_VALID(opts, bpf_kprobe_opts)) > return libbpf_err_ptr(-EINVAL); > > + attach_mode = OPTS_GET(opts, attach_mode, PROBE_ATTACH_MODE_DEFAULT); > retprobe = OPTS_GET(opts, retprobe, false); > offset = OPTS_GET(opts, offset, 0); > pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0); > > legacy = determine_kprobe_perf_type() < 0; > + switch (attach_mode) { > + case PROBE_ATTACH_MODE_LEGACY: > + legacy = true; > + pe_opts.force_ioctl_attach = true; > + break; > + case PROBE_ATTACH_MODE_PERF: > + if (legacy) > + return libbpf_err_ptr(-ENOTSUP); > + pe_opts.force_ioctl_attach = true; > + break; > + case PROBE_ATTACH_MODE_LINK: > + if (legacy || !kernel_supports(prog->obj, FEAT_PERF_LINK)) > + return libbpf_err_ptr(-ENOTSUP); > + break; > + case PROBE_ATTACH_MODE_DEFAULT: > + break; > + default: > + return libbpf_err_ptr(-ENOTSUP); this should have been -EINVAL, I changed it; same for another instance below > + } > + > if (!legacy) { > pfd = perf_event_open_probe(false /* uprobe */, retprobe, > func_name, offset, [...]