From: Jiri Olsa <jolsa@kernel.org>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org, Martin KaFai Lau <martin.lau@linux.dev>,
Eduard Zingerman <eddyz87@gmail.com>,
Song Liu <songliubraving@fb.com>, Yonghong Song <yhs@fb.com>,
Quentin Monnet <qmo@kernel.org>
Subject: [PATCH bpf-next 3/3] bpftool: Add tracing_multi link info output
Date: Sun, 21 Jun 2026 22:45:24 +0200 [thread overview]
Message-ID: <20260621204524.61067-4-jolsa@kernel.org> (raw)
In-Reply-To: <20260621204524.61067-1-jolsa@kernel.org>
Adding bpftool support to show tracing_multi link details,
the new output looks like:
# bpftool link
...
27: tracing_multi prog 93
attach_type trace_fentry_multi obj_id 1 count 3
btf_id addr cookie func [module]
91984 ffffffff824f4a24 a bpf_fentry_test1
91986 ffffffff824f6a84 1e bpf_fentry_test2
91987 ffffffff824f6a94 14 bpf_fentry_test3
pids test_progs(1462)
Assisted-by: Codex:GPT-5
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
tools/bpf/bpftool/link.c | 135 +++++++++++++++++++++++++++++++++++++++
1 file changed, 135 insertions(+)
diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
index bdcd717b0348..58dadee984a0 100644
--- a/tools/bpf/bpftool/link.c
+++ b/tools/bpf/bpftool/link.c
@@ -377,6 +377,31 @@ static __u64 *u64_to_arr(__u64 val)
return (__u64 *) u64_to_ptr(val);
}
+static __u32 *u64_to_u32_arr(__u64 val)
+{
+ return (__u32 *)u64_to_ptr(val);
+}
+
+static struct kernel_sym *find_kernel_sym_by_addr(__u64 addr, bool is_ibt_enabled)
+{
+ struct kernel_sym *sym;
+
+ if (!addr)
+ return NULL;
+
+ /* Load it once for all. */
+ if (!dd.sym_count)
+ kernel_syms_load(&dd);
+ if (!dd.sym_count)
+ return NULL;
+
+ sym = kernel_syms_search(&dd, addr);
+ if (!sym && is_ibt_enabled && addr >= 4)
+ sym = kernel_syms_search(&dd, addr - 4);
+
+ return sym;
+}
+
static void
show_uprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
{
@@ -403,6 +428,43 @@ show_uprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
jsonw_end_array(json_wtr);
}
+static void
+show_tracing_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
+{
+ bool is_ibt_enabled = is_x86_ibt_enabled();
+ __u32 i;
+
+ show_link_attach_type_json(info->tracing_multi.attach_type, wtr);
+ jsonw_uint_field(wtr, "func_cnt", info->tracing_multi.count);
+ jsonw_uint_field(wtr, "obj_id", info->tracing_multi.obj_id);
+ jsonw_name(wtr, "funcs");
+
+ jsonw_start_array(wtr);
+
+ for (i = 0; i < info->tracing_multi.count; i++) {
+ __u64 addr = u64_to_arr(info->tracing_multi.addrs)[i];
+ struct kernel_sym *sym;
+
+ sym = find_kernel_sym_by_addr(addr, is_ibt_enabled);
+
+ jsonw_start_object(wtr);
+ jsonw_uint_field(wtr, "id", u64_to_u32_arr(info->tracing_multi.ids)[i]);
+ jsonw_uint_field(wtr, "addr", addr);
+ if (sym) {
+ jsonw_string_field(wtr, "func", sym->name);
+ if (sym->module[0] == '\0') {
+ jsonw_name(wtr, "module");
+ jsonw_null(wtr);
+ } else {
+ jsonw_string_field(wtr, "module", sym->module);
+ }
+ }
+ jsonw_uint_field(wtr, "cookie", u64_to_arr(info->tracing_multi.cookies)[i]);
+ jsonw_end_object(wtr);
+ }
+ jsonw_end_array(wtr);
+}
+
static void
show_perf_event_kprobe_json(struct bpf_link_info *info, json_writer_t *wtr)
{
@@ -589,6 +651,9 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
case BPF_LINK_TYPE_UPROBE_MULTI:
show_uprobe_multi_json(info, json_wtr);
break;
+ case BPF_LINK_TYPE_TRACING_MULTI:
+ show_tracing_multi_json(info, json_wtr);
+ break;
case BPF_LINK_TYPE_PERF_EVENT:
switch (info->perf_event.type) {
case BPF_PERF_EVENT_EVENT:
@@ -833,6 +898,38 @@ static void show_uprobe_multi_plain(struct bpf_link_info *info)
}
}
+static void show_tracing_multi_plain(struct bpf_link_info *info)
+{
+ bool is_ibt_enabled = is_x86_ibt_enabled();
+ __u32 i;
+
+ if (!info->tracing_multi.count)
+ return;
+
+ printf("\n\t");
+ show_link_attach_type_plain(info->tracing_multi.attach_type);
+ printf("obj_id %u ", info->tracing_multi.obj_id);
+ printf("count %u ", info->tracing_multi.count);
+
+ printf("\n\t%-16s %-16s %-16s %s",
+ "btf_id", "addr", "cookie", "func [module]");
+ for (i = 0; i < info->tracing_multi.count; i++) {
+ __u64 addr = u64_to_arr(info->tracing_multi.addrs)[i];
+ struct kernel_sym *sym;
+
+ sym = find_kernel_sym_by_addr(addr, is_ibt_enabled);
+
+ printf("\n\t%-16u %016llx %-16llx",
+ u64_to_u32_arr(info->tracing_multi.ids)[i],
+ addr, u64_to_arr(info->tracing_multi.cookies)[i]);
+ if (sym) {
+ printf(" %s", sym->name);
+ if (sym->module[0] != '\0')
+ printf(" [%s]", sym->module);
+ }
+ }
+}
+
static void show_perf_event_kprobe_plain(struct bpf_link_info *info)
{
const char *buf;
@@ -989,6 +1086,9 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info)
case BPF_LINK_TYPE_UPROBE_MULTI:
show_uprobe_multi_plain(info);
break;
+ case BPF_LINK_TYPE_TRACING_MULTI:
+ show_tracing_multi_plain(info);
+ break;
case BPF_LINK_TYPE_PERF_EVENT:
switch (info->perf_event.type) {
case BPF_PERF_EVENT_EVENT:
@@ -1029,6 +1129,7 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info)
static int do_show_link(int fd)
{
__u64 *ref_ctr_offsets = NULL, *offsets = NULL, *cookies = NULL;
+ __u32 *ids = NULL;
struct bpf_link_info info;
__u32 len = sizeof(info);
char path_buf[PATH_MAX];
@@ -1114,6 +1215,39 @@ static int do_show_link(int fd)
goto again;
}
}
+ if (info.type == BPF_LINK_TYPE_TRACING_MULTI &&
+ !info.tracing_multi.ids) {
+ count = info.tracing_multi.count;
+ if (count) {
+ ids = calloc(count, sizeof(__u32));
+ if (!ids) {
+ p_err("mem alloc failed");
+ close(fd);
+ return -ENOMEM;
+ }
+ info.tracing_multi.ids = ptr_to_u64(ids);
+
+ addrs = calloc(count, sizeof(__u64));
+ if (!addrs) {
+ p_err("mem alloc failed");
+ free(ids);
+ close(fd);
+ return -ENOMEM;
+ }
+ info.tracing_multi.addrs = ptr_to_u64(addrs);
+
+ cookies = calloc(count, sizeof(__u64));
+ if (!cookies) {
+ p_err("mem alloc failed");
+ free(addrs);
+ free(ids);
+ close(fd);
+ return -ENOMEM;
+ }
+ info.tracing_multi.cookies = ptr_to_u64(cookies);
+ goto again;
+ }
+ }
if (info.type == BPF_LINK_TYPE_PERF_EVENT) {
switch (info.perf_event.type) {
case BPF_PERF_EVENT_TRACEPOINT:
@@ -1153,6 +1287,7 @@ static int do_show_link(int fd)
free(cookies);
free(offsets);
free(addrs);
+ free(ids);
close(fd);
return 0;
}
--
2.54.0
next prev parent reply other threads:[~2026-06-21 20:45 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-21 20:45 [PATCH bpf-next 0/3] bpf: tracing_multi link info support Jiri Olsa
2026-06-21 20:45 ` [PATCH bpf-next 1/3] bpf: Add " Jiri Olsa
2026-06-21 20:45 ` [PATCH bpf-next 2/3] selftests/bpf: Add tracing_multi link info tests Jiri Olsa
2026-06-21 20:53 ` sashiko-bot
2026-06-21 21:31 ` bot+bpf-ci
2026-06-21 20:45 ` Jiri Olsa [this message]
2026-06-21 20:56 ` [PATCH bpf-next 3/3] bpftool: Add tracing_multi link info output sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260621204524.61067-4-jolsa@kernel.org \
--to=jolsa@kernel.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=martin.lau@linux.dev \
--cc=qmo@kernel.org \
--cc=songliubraving@fb.com \
--cc=yhs@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.