Re: [PATCH bpf-next 1/3] libbpf: allow "incomplete" basic tracing SEC() definitions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Apr 8, 2022 at 1:34 PM Andrii Nakryiko <andrii@xxxxxxxxxx> wrote:
>
> In a lot of cases the target of kprobe/kretprobe, tracepoint, raw
> tracepoint, etc BPF program might not be known at the compilation time
> and will be discovered at runtime. This was always a supported case by
> libbpf, with APIs like bpf_program__attach_{kprobe,tracepoint,etc}()
> accepting full target definition, regardless of what was defined in
> SEC() definition in BPF source code.
>
> Unfortunately, up till now libbpf still enforced users to specify at
> least something for the fake target, e.g., SEC("kprobe/whatever"), which
> is cumbersome and somewhat misleading.
>
> This patch allows target-less SEC() definitions for basic tracing BPF
> program types:
>   - kprobe/kretprobe;
>   - multi-kprobe/multi-kretprobe;
>   - tracepoints;
>   - raw tracepoints.
>
> Such target-less SEC() definitions are meant to specify declaratively
> proper BPF program type only. Attachment of them will have to be handled
> programmatically using correct APIs. As such, skeleton's auto-attachment
> of such BPF programs is skipped and generic bpf_program__attach() will
> fail, if attempted, due to the lack of enough target information.
>
> Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx>
> ---
>  tools/lib/bpf/libbpf.c | 69 +++++++++++++++++++++++++++++++-----------
>  1 file changed, 51 insertions(+), 18 deletions(-)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 9deb1fc67f19..81911a1e1f3e 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -8668,22 +8668,22 @@ static const struct bpf_sec_def section_defs[] = {
>         SEC_DEF("socket",               SOCKET_FILTER, 0, SEC_NONE | SEC_SLOPPY_PFX),
>         SEC_DEF("sk_reuseport/migrate", SK_REUSEPORT, BPF_SK_REUSEPORT_SELECT_OR_MIGRATE, SEC_ATTACHABLE | SEC_SLOPPY_PFX),
>         SEC_DEF("sk_reuseport",         SK_REUSEPORT, BPF_SK_REUSEPORT_SELECT, SEC_ATTACHABLE | SEC_SLOPPY_PFX),
> -       SEC_DEF("kprobe/",              KPROBE, 0, SEC_NONE, attach_kprobe),
> +       SEC_DEF("kprobe+",              KPROBE, 0, SEC_NONE, attach_kprobe),
>         SEC_DEF("uprobe+",              KPROBE, 0, SEC_NONE, attach_uprobe),
> -       SEC_DEF("kretprobe/",           KPROBE, 0, SEC_NONE, attach_kprobe),
> +       SEC_DEF("kretprobe+",           KPROBE, 0, SEC_NONE, attach_kprobe),
>         SEC_DEF("uretprobe+",           KPROBE, 0, SEC_NONE, 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.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("usdt+",                KPROBE, 0, SEC_NONE, attach_usdt),
>         SEC_DEF("tc",                   SCHED_CLS, 0, SEC_NONE),
>         SEC_DEF("classifier",           SCHED_CLS, 0, SEC_NONE | SEC_SLOPPY_PFX | SEC_DEPRECATED),
>         SEC_DEF("action",               SCHED_ACT, 0, SEC_NONE | SEC_SLOPPY_PFX),
> -       SEC_DEF("tracepoint/",          TRACEPOINT, 0, SEC_NONE, attach_tp),
> -       SEC_DEF("tp/",                  TRACEPOINT, 0, SEC_NONE, attach_tp),
> -       SEC_DEF("raw_tracepoint/",      RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),
> -       SEC_DEF("raw_tp/",              RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),
> -       SEC_DEF("raw_tracepoint.w/",    RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),
> -       SEC_DEF("raw_tp.w/",            RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),
> +       SEC_DEF("tracepoint+",          TRACEPOINT, 0, SEC_NONE, attach_tp),
> +       SEC_DEF("tp+",                  TRACEPOINT, 0, SEC_NONE, attach_tp),
> +       SEC_DEF("raw_tracepoint+",      RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),
> +       SEC_DEF("raw_tp+",              RAW_TRACEPOINT, 0, SEC_NONE, attach_raw_tp),
> +       SEC_DEF("raw_tracepoint.w+",    RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),
> +       SEC_DEF("raw_tp.w+",            RAW_TRACEPOINT_WRITABLE, 0, SEC_NONE, attach_raw_tp),
>         SEC_DEF("tp_btf/",              TRACING, BPF_TRACE_RAW_TP, SEC_ATTACH_BTF, attach_trace),
>         SEC_DEF("fentry/",              TRACING, BPF_TRACE_FENTRY, SEC_ATTACH_BTF, attach_trace),
>         SEC_DEF("fmod_ret/",            TRACING, BPF_MODIFY_RETURN, SEC_ATTACH_BTF, attach_trace),
> @@ -10411,6 +10411,12 @@ static int attach_kprobe(const struct bpf_program *prog, long cookie, struct bpf
>         char *func;
>         int n;
>
> +       *link = NULL;
> +
> +       /* no auto-attach for SEC("kprobe") and SEC("kretprobe") */
> +       if (strcmp(prog->sec_name, "kprobe") == 0 || strcmp(prog->sec_name, "kretprobe") == 0)
> +               return 0;
> +
>         opts.retprobe = str_has_pfx(prog->sec_name, "kretprobe/");
>         if (opts.retprobe)
>                 func_name = prog->sec_name + sizeof("kretprobe/") - 1;
> @@ -10441,6 +10447,13 @@ static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, stru
>         char *pattern;
>         int n;
>
> +       *link = NULL;
> +
> +       /* no auto-attach for SEC("kprobe.multi") and SEC("kretprobe.multi") */
> +       if (strcmp(prog->sec_name, "kprobe.multi") == 0 ||
> +           strcmp(prog->sec_name, "kretprobe.multi") == 0)
> +               return 0;
> +
>         opts.retprobe = str_has_pfx(prog->sec_name, "kretprobe.multi/");
>         if (opts.retprobe)
>                 spec = prog->sec_name + sizeof("kretprobe.multi/") - 1;
> @@ -11145,6 +11158,12 @@ static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_lin
>         if (!sec_name)
>                 return -ENOMEM;
>
> +       *link = NULL;
> +
> +       /* no auto-attach for SEC("tp") or SEC("tracepoint") */
> +       if (strcmp(prog->sec_name, "tp") == 0 || strcmp(prog->sec_name, "tracepoint") == 0)
> +               return 0;
> +
>         /* extract "tp/<category>/<name>" or "tracepoint/<category>/<name>" */
>         if (str_has_pfx(prog->sec_name, "tp/"))
>                 tp_cat = sec_name + sizeof("tp/") - 1;
> @@ -11196,20 +11215,34 @@ struct bpf_link *bpf_program__attach_raw_tracepoint(const struct bpf_program *pr
>  static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link)
>  {
>         static const char *const prefixes[] = {
> -               "raw_tp/",
> -               "raw_tracepoint/",
> -               "raw_tp.w/",
> -               "raw_tracepoint.w/",
> +               "raw_tp",
> +               "raw_tracepoint",
> +               "raw_tp.w",
> +               "raw_tracepoint.w",
>         };
>         size_t i;
>         const char *tp_name = NULL;
>
> +       *link = NULL;
> +
>         for (i = 0; i < ARRAY_SIZE(prefixes); i++) {
> -               if (str_has_pfx(prog->sec_name, prefixes[i])) {
> -                       tp_name = prog->sec_name + strlen(prefixes[i]);
> -                       break;
> -               }
> +               size_t pfx_len;
> +
> +               if (!str_has_pfx(prog->sec_name, prefixes[i]))
> +                       continue;
> +
> +               pfx_len = strlen(prefixes[i]);
> +               /* no auto-attach case of, e.g., SEC("raw_tp") */
> +               if (prog->sec_name[pfx_len] == '\0')
> +                       return 0;
> +
> +               if (prog->sec_name[pfx_len] != '/')
> +                       continue;

Maybe introduce a sec_has_pfx() function with tri-state return value:
1 for match with tp_name, 0, for match without tp_name, -1 for no match.

> +
> +               tp_name = prog->sec_name + pfx_len + 1;
> +               break;
>         }
> +
>         if (!tp_name) {
>                 pr_warn("prog '%s': invalid section name '%s'\n",
>                         prog->name, prog->sec_name);
> --
> 2.30.2
>



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux