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 <[email protected]>
---
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