[PATCH bpf-next 05/13] libbpf: Add tracing_multi link support for bpf progs
From: Leon Hwang <hidden>
Date: 2026-08-09 15:02:56
Also in:
bpf, linux-kselftest, lkml
Subsystem:
bpf [general] (safe dynamic programs and tools), bpf [library] (libbpf), the rest · Maintainers:
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Linus Torvalds
By design, a tracing_multi link does not support both kernel functions
and bpf progs at the same time.
In libbpf, the bpf_tracing_multi_opts options provides two new fields for
tracing bpf progs:
* 'fds': the fd array of the target bpf progs. One fd must be provided
multiple times for multiple targets.
* 'funcs': the function name array of the target bpf progs.
The 'cnt' field indicates the size of both 'fds' and 'funcs' arrays.
The 'funcs' will be translated to 'ids' by 'libbpf_find_prog_btf_id()'.
At last, 'fds'+'ids' will be passed to kernel.
Signed-off-by: Leon Hwang <redacted>
---
tools/lib/bpf/bpf.c | 1 +
tools/lib/bpf/bpf.h | 2 ++
tools/lib/bpf/libbpf.c | 37 +++++++++++++++++++++++++++++++++----
tools/lib/bpf/libbpf.h | 4 +++-
4 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 96819c082c77..a20585174903 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c@@ -852,6 +852,7 @@ int bpf_link_create(int prog_fd, int target_fd, attr.link_create.tracing_multi.ids = ptr_to_u64(OPTS_GET(opts, tracing_multi.ids, 0)); attr.link_create.tracing_multi.cookies = ptr_to_u64(OPTS_GET(opts, tracing_multi.cookies, 0)); attr.link_create.tracing_multi.cnt = OPTS_GET(opts, tracing_multi.cnt, 0); + attr.link_create.tracing_multi.fds = ptr_to_u64(OPTS_GET(opts, tracing_multi.fds, 0)); if (!OPTS_ZEROED(opts, tracing_multi)) return libbpf_err(-EINVAL); break;
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 7534a593edae..63961db29b74 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h@@ -474,6 +474,8 @@ struct bpf_link_create_opts { const __u32 *ids; const __u64 *cookies; __u32 cnt; + __u32 :32; + const int *fds; } tracing_multi; }; size_t :0;
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 514e4e9daa82..d698a64ff800 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c@@ -12687,10 +12687,12 @@ bpf_program__attach_tracing_multi(const struct bpf_program *prog, const char *pa { LIBBPF_OPTS(bpf_link_create_opts, lopts); int prog_fd, link_fd, err, cnt; + struct bpf_link *link = NULL; __u32 *free_ids = NULL; - struct bpf_link *link; const __u64 *cookies; + const char **funcs; const __u32 *ids; + const int *fds; if (!OPTS_VALID(opts, bpf_tracing_multi_opts)) return libbpf_err_ptr(-EINVAL);
@@ -12705,12 +12707,22 @@ bpf_program__attach_tracing_multi(const struct bpf_program *prog, const char *pa cnt = OPTS_GET(opts, cnt, 0); ids = OPTS_GET(opts, ids, NULL); cookies = OPTS_GET(opts, cookies, NULL); + fds = OPTS_GET(opts, fds, NULL); + funcs = OPTS_GET(opts, funcs, NULL); - if (!!ids != !!cnt) + if (ids && fds) + return libbpf_err_ptr(-EINVAL); + if (!!fds != !!funcs) + return libbpf_err_ptr(-EINVAL); + if (fds && !cnt) return libbpf_err_ptr(-EINVAL); - if (pattern && (ids || cookies)) + if (ids && !cnt) return libbpf_err_ptr(-EINVAL); - if (!pattern && !ids) + if (!fds && !ids && cnt) + return libbpf_err_ptr(-EINVAL); + if (pattern && (fds || ids || cookies)) + return libbpf_err_ptr(-EINVAL); + if (!pattern && !ids && !fds) return libbpf_err_ptr(-EINVAL); if (pattern) {
@@ -12720,11 +12732,28 @@ bpf_program__attach_tracing_multi(const struct bpf_program *prog, const char *pa if (cnt == 0) return libbpf_err_ptr(-EINVAL); ids = (const __u32 *) free_ids; + } else if (fds) { + size_t cap = 0; + int i; + + err = libbpf_ensure_mem((void **) &free_ids, &cap, sizeof(*free_ids), cnt); + if (err) + return libbpf_err_ptr(err); + + for (i = 0; i < cnt; i++) { + err = libbpf_find_prog_btf_id(funcs[i], fds[i], prog->obj->token_fd); + if (err < 0) + goto error; + + free_ids[i] = err; + } + ids = (const __u32 *) free_ids; } lopts.tracing_multi.ids = ids; lopts.tracing_multi.cookies = cookies; lopts.tracing_multi.cnt = cnt; + lopts.tracing_multi.fds = fds; link = calloc(1, sizeof(*link)); if (!link) {
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index b965ad571540..7b2cfa1ad572 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h@@ -732,10 +732,12 @@ struct bpf_tracing_multi_opts { const __u32 *ids; const __u64 *cookies; size_t cnt; + const int *fds; + const char **funcs; size_t :0; }; -#define bpf_tracing_multi_opts__last_field cnt +#define bpf_tracing_multi_opts__last_field funcs LIBBPF_API struct bpf_link * bpf_program__attach_tracing_multi(const struct bpf_program *prog, const char *pattern,
--
2.55.0