On Tue, Apr 12, 2022 at 9:56 AM Kui-Feng Lee <kuifeng@xxxxxx> wrote: > > Add a cookie field to the attributes of bpf_link_create(). > Add bpf_program__attach_trace_opts() to attach a cookie to a link. > > Signed-off-by: Kui-Feng Lee <kuifeng@xxxxxx> > --- Please stick to "libbpf: " prefix for patch subject, we don't use "lib/bpf: " > tools/lib/bpf/bpf.c | 7 +++++++ > tools/lib/bpf/bpf.h | 3 +++ > tools/lib/bpf/libbpf.c | 33 +++++++++++++++++++++++++++++++++ > tools/lib/bpf/libbpf.h | 12 ++++++++++++ > tools/lib/bpf/libbpf.map | 1 + > 5 files changed, 56 insertions(+) > > diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c > index cf27251adb92..c2454979c3c4 100644 > --- a/tools/lib/bpf/bpf.c > +++ b/tools/lib/bpf/bpf.c > @@ -863,6 +863,13 @@ int bpf_link_create(int prog_fd, int target_fd, > if (!OPTS_ZEROED(opts, kprobe_multi)) > return libbpf_err(-EINVAL); > break; > + case BPF_TRACE_FENTRY: > + case BPF_TRACE_FEXIT: > + case BPF_MODIFY_RETURN: > + attr.link_create.tracing.bpf_cookie = OPTS_GET(opts, tracing.bpf_cookie, 0); > + if (!OPTS_ZEROED(opts, tracing)) > + return libbpf_err(-EINVAL); > + break; > default: > if (!OPTS_ZEROED(opts, flags)) > return libbpf_err(-EINVAL); > diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h > index f4b4afb6d4ba..4cdbabcccefc 100644 > --- a/tools/lib/bpf/bpf.h > +++ b/tools/lib/bpf/bpf.h > @@ -410,6 +410,9 @@ struct bpf_link_create_opts { > __u32 iter_info_len; > __u32 target_btf_id; > union { > + struct { > + __u64 bpf_cookie; > + } tracing; > struct { > __u64 bpf_cookie; > } perf_event; > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index bf4f7ac54ebf..8586e1efd780 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -11262,6 +11262,39 @@ struct bpf_link *bpf_program__attach_trace(const struct bpf_program *prog) > return bpf_program__attach_btf_id(prog); > } > > +struct bpf_link *bpf_program__attach_trace_opts(const struct bpf_program *prog, > + const struct bpf_trace_opts *opts) > +{ > + char errmsg[STRERR_BUFSIZE]; > + struct bpf_link *link; > + int prog_fd, pfd; > + unnecessary empty line, LIBBPF_OPTS is a variable declaration, so keep it together with other variables > + LIBBPF_OPTS(bpf_link_create_opts, link_opts); > + > + prog_fd = bpf_program__fd(prog); > + if (prog_fd < 0) { > + pr_warn("prog '%s': can't attach before loaded\n", prog->name); > + return libbpf_err_ptr(-EINVAL); > + } > + > + link = calloc(1, sizeof(*link)); > + if (!link) > + return libbpf_err_ptr(-ENOMEM); > + link->detach = &bpf_link__detach_fd; > + > + link_opts.tracing.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0); > + pfd = bpf_link_create(prog_fd, 0, prog->expected_attach_type, &link_opts); so this won't work on old kernels that don't support creating fentry/fexit links through LINK_CREATE. Let's for now check if bpf_cookie is zero, then redirect to bpf_program__attach_trace(). Ideally we should perform feature detection of ability to use LINK_CREATE to attach fentry and have a unified single bpf_program__attach_btf_id() implementation that will handle all that internally > + if (pfd < 0) { > + pfd = -errno; > + free(link); > + pr_warn("prog '%s': failed to attach: %s\n", > + prog->name, libbpf_strerror_r(pfd, errmsg, sizeof(errmsg))); > + return libbpf_err_ptr(pfd); > + } > + link->fd = pfd; > + return (struct bpf_link *)link; > +} > + > struct bpf_link *bpf_program__attach_lsm(const struct bpf_program *prog) > { > return bpf_program__attach_btf_id(prog); > diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h > index 63d66f1adf1a..e0dd3f9a5aca 100644 > --- a/tools/lib/bpf/libbpf.h > +++ b/tools/lib/bpf/libbpf.h > @@ -563,8 +563,20 @@ bpf_program__attach_tracepoint_opts(const struct bpf_program *prog, > LIBBPF_API struct bpf_link * > bpf_program__attach_raw_tracepoint(const struct bpf_program *prog, > const char *tp_name); > + > +struct bpf_trace_opts { > + /* size of this struct, for forward/backward compatibility */ > + size_t sz; > + /* custom user-provided value fetchable through bpf_get_attach_cookie() */ > + __u64 bpf_cookie; > +}; > +#define bpf_trace_opts__last_field bpf_cookie > + > LIBBPF_API struct bpf_link * > bpf_program__attach_trace(const struct bpf_program *prog); > +LIBBPF_API struct bpf_link * > +bpf_program__attach_trace_opts(const struct bpf_program *prog, const struct bpf_trace_opts *opts); > + > LIBBPF_API struct bpf_link * > bpf_program__attach_lsm(const struct bpf_program *prog); > LIBBPF_API struct bpf_link * > diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map > index 82f6d62176dd..9235da802e31 100644 > --- a/tools/lib/bpf/libbpf.map > +++ b/tools/lib/bpf/libbpf.map > @@ -424,6 +424,7 @@ LIBBPF_0.6.0 { > LIBBPF_0.7.0 { > global: > bpf_btf_load; > + bpf_program__attach_trace_opts; this should go into LIBBPF_0.8.0 > bpf_program__expected_attach_type; > bpf_program__log_buf; > bpf_program__log_level; > -- > 2.30.2 >