* [PATCH bpf-next 0/3] bpf: tracing_multi link info support
@ 2026-06-21 20:45 Jiri Olsa
2026-06-21 20:45 ` [PATCH bpf-next 1/3] bpf: Add " Jiri Olsa
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Jiri Olsa @ 2026-06-21 20:45 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Quentin Monnet
hi,
adding link info support for tracing_multi link.
Adding the kernel support with related selftests and bpftool support
to display the tracing_multi link info, the 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)
thanks,
jirka
---
Jiri Olsa (3):
bpf: Add tracing_multi link info support
selftests/bpf: Add tracing_multi link info tests
bpftool: Add tracing_multi link info output
include/uapi/linux/bpf.h | 9 +++
kernel/trace/bpf_trace.c | 55 +++++++++++++++++
tools/bpf/bpftool/link.c | 135 ++++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 9 +++
tools/testing/selftests/bpf/prog_tests/fill_link_info.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/testing/selftests/bpf/progs/test_fill_link_info.c | 6 ++
6 files changed, 456 insertions(+)
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH bpf-next 1/3] bpf: Add tracing_multi link info support 2026-06-21 20:45 [PATCH bpf-next 0/3] bpf: tracing_multi link info support Jiri Olsa @ 2026-06-21 20:45 ` 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:45 ` [PATCH bpf-next 3/3] bpftool: Add tracing_multi link info output Jiri Olsa 2 siblings, 0 replies; 10+ messages in thread From: Jiri Olsa @ 2026-06-21 20:45 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song, Quentin Monnet Adding BPF_OBJ_GET_INFO_BY_FD support for tracing_multi links. We expose following tracing_multi link data: - attach_type of the program - number of ids - array of BTF ids - array of its related kernel addresses - array of cookies The change follows the kprobe_multi and uprobe_multi link-info convention of optional output arrays with an in/out count, On top of standard tracing link data we also expose addresses, because they are useful info for user (especially when the attachment was done via pattern). This data is hidden when kallsyms does not allow exposing kernel pointer values. Assisted-by: Codex:GPT-5 Signed-off-by: Jiri Olsa <jolsa@kernel.org> --- include/uapi/linux/bpf.h | 9 ++++++ kernel/trace/bpf_trace.c | 55 ++++++++++++++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 9 ++++++ 3 files changed, 73 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 89b36de5fdbb..80423ccc6b57 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -6839,6 +6839,15 @@ struct bpf_link_info { __u32 flags; __u32 pid; } uprobe_multi; + struct { + __u32 attach_type; + __u32 count; /* in/out: tracing_multi target count */ + __u32 obj_id; + __u32 :32; + __aligned_u64 ids; + __aligned_u64 addrs; + __aligned_u64 cookies; + } tracing_multi; struct { __u32 type; /* enum bpf_perf_event_type */ __u32 :32; diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 82f8feea6931..fdab4ec5ad4f 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -3699,6 +3699,60 @@ static void bpf_tracing_multi_link_dealloc(struct bpf_link *link) kvfree(tr_link); } +static int bpf_tracing_multi_link_fill_link_info(const struct bpf_link *link, + struct bpf_link_info *info) +{ + u64 __user *ucookies = u64_to_user_ptr(info->tracing_multi.cookies); + u64 __user *uaddrs = u64_to_user_ptr(info->tracing_multi.addrs); + u32 __user *uids = u64_to_user_ptr(info->tracing_multi.ids); + struct bpf_tracing_multi_link *tr_link; + u32 ucount = info->tracing_multi.count; + bool has_cookies, show_addrs; + int err = 0; + + if ((uids || ucookies || uaddrs) && !ucount) + return -EINVAL; + + tr_link = container_of(link, struct bpf_tracing_multi_link, link); + + info->tracing_multi.attach_type = tr_link->link.attach_type; + info->tracing_multi.count = tr_link->nodes_cnt; + info->tracing_multi.obj_id = btf_obj_id(tr_link->link.prog->aux->attach_btf); + + if (!uids && !ucookies && !uaddrs) + return 0; + + if (ucount < tr_link->nodes_cnt) + err = -ENOSPC; + else + ucount = tr_link->nodes_cnt; + + has_cookies = !!tr_link->cookies; + show_addrs = kallsyms_show_value(current_cred()); + + for (int i = 0; i < ucount; i++) { + struct bpf_tracing_multi_node *mnode = &tr_link->nodes[i]; + u64 addr, cookie; + u32 id; + + bpf_trampoline_unpack_key(mnode->trampoline->key, NULL, &id); + + addr = show_addrs ? mnode->trampoline->ip : 0; + cookie = has_cookies ? tr_link->cookies[i] : 0; + + if (uids && put_user(id, uids + i)) + return -EFAULT; + if (uaddrs && put_user(addr, uaddrs + i)) + return -EFAULT; + if (ucookies && put_user(cookie, ucookies + i)) + return -EFAULT; + + cond_resched(); + } + + return err; +} + #ifdef CONFIG_PROC_FS static void bpf_tracing_multi_show_fdinfo(const struct bpf_link *link, struct seq_file *seq) @@ -3729,6 +3783,7 @@ static void bpf_tracing_multi_show_fdinfo(const struct bpf_link *link, static const struct bpf_link_ops bpf_tracing_multi_link_lops = { .release = bpf_tracing_multi_link_release, .dealloc_deferred = bpf_tracing_multi_link_dealloc, + .fill_link_info = bpf_tracing_multi_link_fill_link_info, #ifdef CONFIG_PROC_FS .show_fdinfo = bpf_tracing_multi_show_fdinfo, #endif diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 89b36de5fdbb..80423ccc6b57 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -6839,6 +6839,15 @@ struct bpf_link_info { __u32 flags; __u32 pid; } uprobe_multi; + struct { + __u32 attach_type; + __u32 count; /* in/out: tracing_multi target count */ + __u32 obj_id; + __u32 :32; + __aligned_u64 ids; + __aligned_u64 addrs; + __aligned_u64 cookies; + } tracing_multi; struct { __u32 type; /* enum bpf_perf_event_type */ __u32 :32; -- 2.54.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH bpf-next 2/3] selftests/bpf: Add tracing_multi link info tests 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 ` Jiri Olsa 2026-06-21 20:53 ` sashiko-bot 2026-06-21 21:31 ` bot+bpf-ci 2026-06-21 20:45 ` [PATCH bpf-next 3/3] bpftool: Add tracing_multi link info output Jiri Olsa 2 siblings, 2 replies; 10+ messages in thread From: Jiri Olsa @ 2026-06-21 20:45 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song, Quentin Monnet Adding tracing_multi link info tests that follow the kprobe_multi and uprobe_multi tests logic. Assisted-by: Codex:GPT-5 Signed-off-by: Jiri Olsa <jolsa@kernel.org> --- .../selftests/bpf/prog_tests/fill_link_info.c | 242 ++++++++++++++++++ .../selftests/bpf/progs/test_fill_link_info.c | 6 + 2 files changed, 248 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c index f589eefbf9fb..969f04ee9ac6 100644 --- a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c +++ b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c @@ -4,6 +4,7 @@ #include <string.h> #include <linux/bpf.h> #include <linux/limits.h> +#include <bpf/btf.h> #include <test_progs.h> #include "trace_helpers.h" #include "test_fill_link_info.skel.h" @@ -24,6 +25,22 @@ static __u64 kmulti_cookies[] = { 3, 1, 2 }; #define KPROBE_FUNC "bpf_fentry_test1" static __u64 kprobe_addr; +static const char * const tmulti_syms[] = { + "bpf_fentry_test2", + "bpf_fentry_test1", + "bpf_fentry_test3", +}; + +static __u64 tmulti_cookies[] = { 30, 10, 20 }; +#define TRACING_MULTI_CNT ARRAY_SIZE(tmulti_syms) + +struct tmulti_target { + const char *name; + __u64 addr; + __u64 cookie; + __u32 id; +}; + #define UPROBE_FILE "/proc/self/exe" static ssize_t uprobe_offset; /* uprobe attach point */ @@ -396,6 +413,224 @@ static void test_kprobe_multi_fill_link_info(struct test_fill_link_info *skel, bpf_link__destroy(link); } +static int tmulti_target_cmp(const void *a, const void *b) +{ + const struct tmulti_target *ta = a; + const struct tmulti_target *tb = b; + + return (ta->id > tb->id) - (ta->id < tb->id); +} + +static int setup_tmulti_targets(const struct bpf_program *prog, + struct tmulti_target *targets, + __u32 *obj_id) +{ + struct bpf_prog_info prog_info; + __u32 len = sizeof(prog_info); + struct btf *btf; + int err, i; + __s32 id; + + btf = btf__load_vmlinux_btf(); + if (!ASSERT_OK_PTR(btf, "btf__load_vmlinux_btf")) + return -1; + + for (i = 0; i < TRACING_MULTI_CNT; i++) { + id = btf__find_by_name_kind(btf, tmulti_syms[i], BTF_KIND_FUNC); + if (!ASSERT_GT(id, 0, "btf__find_by_name_kind")) + goto error; + + targets[i].name = tmulti_syms[i]; + targets[i].addr = ksym_get_addr(tmulti_syms[i]); + targets[i].cookie = tmulti_cookies[i]; + targets[i].id = id; + } + + memset(&prog_info, 0, len); + err = bpf_prog_get_info_by_fd(bpf_program__fd(prog), &prog_info, &len); + if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd")) + goto error; + if (!ASSERT_GT(prog_info.attach_btf_obj_id, 0, "attach_btf_obj_id")) + goto error; + *obj_id = prog_info.attach_btf_obj_id; + + /* + * The kernel tracing multi attach sorts ids. We sort as well, + * so we can easily compare ids and cookies later. + */ + qsort(targets, TRACING_MULTI_CNT, sizeof(targets[0]), tmulti_target_cmp); + btf__free(btf); + return 0; + +error: + btf__free(btf); + return -1; +} + +static int verify_tracing_multi_link_info(int fd, const struct bpf_program *prog, + const struct tmulti_target *targets, + __u32 obj_id, bool has_cookies) +{ + enum bpf_attach_type attach_type = bpf_program__expected_attach_type(prog); + __u64 addrs[TRACING_MULTI_CNT], cookies[TRACING_MULTI_CNT]; + __u32 ids[TRACING_MULTI_CNT]; + struct bpf_link_info info; + __u32 len = sizeof(info); + int err, i; + + memset(&info, 0, sizeof(info)); + err = bpf_link_get_info_by_fd(fd, &info, &len); + if (!ASSERT_OK(err, "bpf_link_get_info_by_fd")) + return -1; + + if (!ASSERT_EQ(info.type, BPF_LINK_TYPE_TRACING_MULTI, "info.type")) + return -1; + + ASSERT_EQ(info.tracing_multi.attach_type, attach_type, "info.tracing_multi.attach_type"); + ASSERT_EQ(info.tracing_multi.count, TRACING_MULTI_CNT, "info.tracing_multi.count"); + + memset(ids, 0, sizeof(ids)); + memset(cookies, 0, sizeof(cookies)); + memset(addrs, 0, sizeof(addrs)); + + info.tracing_multi.ids = ptr_to_u64(ids); + info.tracing_multi.addrs = ptr_to_u64(addrs); + info.tracing_multi.cookies = has_cookies ? ptr_to_u64(cookies) : 0; + info.tracing_multi.count = TRACING_MULTI_CNT; + + err = bpf_link_get_info_by_fd(fd, &info, &len); + if (!ASSERT_OK(err, "bpf_link_get_info_by_fd")) + return -1; + + if (!ASSERT_EQ(info.type, BPF_LINK_TYPE_TRACING_MULTI, "info.type")) + return -1; + + ASSERT_EQ(info.tracing_multi.attach_type, attach_type, "info.tracing_multi.attach_type"); + ASSERT_EQ(info.tracing_multi.count, TRACING_MULTI_CNT, "info.tracing_multi.count"); + ASSERT_EQ(info.tracing_multi.obj_id, obj_id, "tracing_multi.target_obj_ids"); + + for (i = 0; i < TRACING_MULTI_CNT; i++) { + ASSERT_EQ(ids[i], targets[i].id, "tracing_multi.target_btf_ids"); + ASSERT_EQ(cookies[i], has_cookies ? targets[i].cookie : 0, "tracing_multi.cookies"); + + if (targets[i].addr) { + struct ksym *ksym; + + if (!ASSERT_NEQ(addrs[i], 0, "tracing_multi.addrs")) + return -1; + ksym = ksym_search(addrs[i]); + if (!ASSERT_OK_PTR(ksym, "ksym_search")) + return -1; + ASSERT_STREQ(ksym->name, targets[i].name, "tracing_multi.addr_name"); + } else { + ASSERT_EQ(addrs[i], 0, "tracing_multi.addrs"); + } + } + + return 0; +} + +static void verify_tracing_multi_invalid_user_buffer(int fd, const struct tmulti_target *targets) +{ + __u32 ids[TRACING_MULTI_CNT] = {}; + struct bpf_link_info info; + __u32 len = sizeof(info); + int err, i; + + /* Wrong info setup (ids != NULL and cnt == 0) -> EINVAL */ + memset(&info, 0, sizeof(info)); + info.tracing_multi.ids = ptr_to_u64(ids); + err = bpf_link_get_info_by_fd(fd, &info, &len); + ASSERT_EQ(err, -EINVAL, "tracing_multi.invalid_count"); + + /* Smaller than actuall count provided -> ENOSPC */ + memset(ids, 0, sizeof(ids)); + memset(&info, 0, sizeof(info)); + info.tracing_multi.ids = ptr_to_u64(ids); + info.tracing_multi.count = TRACING_MULTI_CNT - 1; + err = bpf_link_get_info_by_fd(fd, &info, &len); + ASSERT_EQ(err, -ENOSPC, "tracing_multi.small_count"); + for (i = 0; i < TRACING_MULTI_CNT - 1; i++) + ASSERT_EQ(ids[i], targets[i].id, "tracing_multi.partial_ids"); + /* check that the last entry is not populated */ + ASSERT_EQ(ids[i], 0, "tracing_multi.partial_ids"); + + /* Bigger than actuall count provided -> OK */ + memset(ids, 0, sizeof(ids)); + memset(&info, 0, sizeof(info)); + info.tracing_multi.ids = ptr_to_u64(ids); + info.tracing_multi.count = TRACING_MULTI_CNT + 1; + err = bpf_link_get_info_by_fd(fd, &info, &len); + ASSERT_OK(err, "tracing_multi.big_count"); + for (i = 0; i < TRACING_MULTI_CNT; i++) + ASSERT_EQ(ids[i], targets[i].id, "tracing_multi.ids"); + + /* Invalid ids pointer -> EFAULT */ + memset(&info, 0, sizeof(info)); + info.tracing_multi.ids = 0x1; + info.tracing_multi.count = TRACING_MULTI_CNT; + err = bpf_link_get_info_by_fd(fd, &info, &len); + ASSERT_EQ(err, -EFAULT, "tracing_multi.bad_btf_ids"); + + /* Invalid cookies pointer -> EFAULT */ + memset(&info, 0, sizeof(info)); + info.tracing_multi.cookies = 0x1; + info.tracing_multi.count = TRACING_MULTI_CNT; + err = bpf_link_get_info_by_fd(fd, &info, &len); + ASSERT_EQ(err, -EFAULT, "tracing_multi.bad_cookies"); + + /* Invalid addrs pointer -> EFAULT */ + memset(&info, 0, sizeof(info)); + info.tracing_multi.addrs = 0x1; + info.tracing_multi.count = TRACING_MULTI_CNT; + err = bpf_link_get_info_by_fd(fd, &info, &len); + ASSERT_EQ(err, -EFAULT, "tracing_multi.bad_cookies"); +} + +static void test_tracing_multi_fill_link_info(struct test_fill_link_info *skel, + bool has_cookies, bool invalid) +{ + LIBBPF_OPTS(bpf_tracing_multi_opts, opts); + struct tmulti_target targets[TRACING_MULTI_CNT]; + __u32 ids[TRACING_MULTI_CNT], obj_id; + __u64 cookies[TRACING_MULTI_CNT]; + struct bpf_link *link; + int link_fd, err, i; + +#ifndef __x86_64__ + test__skip(); + return; +#endif + + if (setup_tmulti_targets(skel->progs.tmulti_run, targets, &obj_id)) + return; + + for (i = 0; i < TRACING_MULTI_CNT; i++) { + ids[i] = targets[i].id; + cookies[i] = targets[i].cookie; + } + + opts.ids = ids; + opts.cnt = TRACING_MULTI_CNT; + if (has_cookies) + opts.cookies = cookies; + + link = bpf_program__attach_tracing_multi(skel->progs.tmulti_run, NULL, &opts); + if (!ASSERT_OK_PTR(link, "bpf_program__attach_tracing_multi")) + return; + + link_fd = bpf_link__fd(link); + if (invalid) { + verify_tracing_multi_invalid_user_buffer(link_fd, targets); + } else { + err = verify_tracing_multi_link_info(link_fd, skel->progs.tmulti_run, + targets, obj_id, has_cookies); + ASSERT_OK(err, "verify_tracing_multi_link_info"); + } + + bpf_link__destroy(link); +} + #define SEC(name) __attribute__((section(name), used)) static short uprobe_link_info_sema_1 SEC(".probes"); @@ -640,6 +875,13 @@ void test_fill_link_info(void) if (test__start_subtest("kprobe_multi_invalid_ubuff")) test_kprobe_multi_fill_link_info(skel, true, true, true); + if (test__start_subtest("tracing_multi_link_info")) { + test_tracing_multi_fill_link_info(skel, false, false); + test_tracing_multi_fill_link_info(skel, true, false); + } + if (test__start_subtest("tracing_multi_invalid_ubuff")) + test_tracing_multi_fill_link_info(skel, true, true); + if (test__start_subtest("uprobe_multi_link_info")) test_uprobe_multi_fill_link_info(skel, false, false); if (test__start_subtest("uretprobe_multi_link_info")) diff --git a/tools/testing/selftests/bpf/progs/test_fill_link_info.c b/tools/testing/selftests/bpf/progs/test_fill_link_info.c index 137bd6292163..c85081538e93 100644 --- a/tools/testing/selftests/bpf/progs/test_fill_link_info.c +++ b/tools/testing/selftests/bpf/progs/test_fill_link_info.c @@ -58,4 +58,10 @@ int BPF_PROG(umulti_run) return 0; } +SEC("fentry.multi") +int BPF_PROG(tmulti_run) +{ + return 0; +} + char _license[] SEC("license") = "GPL"; -- 2.54.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 2/3] selftests/bpf: Add tracing_multi link info tests 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-22 10:35 ` Jiri Olsa 2026-06-21 21:31 ` bot+bpf-ci 1 sibling, 1 reply; 10+ messages in thread From: sashiko-bot @ 2026-06-21 20:53 UTC (permalink / raw) To: Jiri Olsa; +Cc: bpf Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Low] Incorrect assertion failure message tag for invalid `addrs` pointer test. -- commit edec3b6e703fee4df106f0b3f019e87b22c606fc Author: Jiri Olsa <jolsa@kernel.org> selftests/bpf: Add tracing_multi link info tests This commit adds new tests for tracing_multi link info. The tests follow the existing logic used for kprobe_multi and uprobe_multi tests. > diff --git a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > index f589eefbf9fbd..969f04ee9ac6a 100644 > --- a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > +++ b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c [ ... ] > +static void verify_tracing_multi_invalid_user_buffer(int fd, const struct tmulti_target *targets) > +{ > + __u32 ids[TRACING_MULTI_CNT] = {}; > + struct bpf_link_info info; > + __u32 len = sizeof(info); > + int err, i; [ ... ] > + /* Invalid cookies pointer -> EFAULT */ > + memset(&info, 0, sizeof(info)); > + info.tracing_multi.cookies = 0x1; > + info.tracing_multi.count = TRACING_MULTI_CNT; > + err = bpf_link_get_info_by_fd(fd, &info, &len); > + ASSERT_EQ(err, -EFAULT, "tracing_multi.bad_cookies"); > + > + /* Invalid addrs pointer -> EFAULT */ > + memset(&info, 0, sizeof(info)); > + info.tracing_multi.addrs = 0x1; > + info.tracing_multi.count = TRACING_MULTI_CNT; > + err = bpf_link_get_info_by_fd(fd, &info, &len); > + ASSERT_EQ(err, -EFAULT, "tracing_multi.bad_cookies"); [Severity: Low] This isn't a bug, but is this tag a copy-paste error? The comment mentions testing an invalid addrs pointer, but the assertion in verify_tracing_multi_invalid_user_buffer() uses the "tracing_multi.bad_cookies" tag rather than something like "tracing_multi.bad_addrs". > +} [ ... ] -- Sashiko AI review · https://sashiko.dev/#/patchset/20260621204524.61067-1-jolsa@kernel.org?part=2 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 2/3] selftests/bpf: Add tracing_multi link info tests 2026-06-21 20:53 ` sashiko-bot @ 2026-06-22 10:35 ` Jiri Olsa 0 siblings, 0 replies; 10+ messages in thread From: Jiri Olsa @ 2026-06-22 10:35 UTC (permalink / raw) To: sashiko-reviews; +Cc: bpf On Sun, Jun 21, 2026 at 08:53:50PM +0000, sashiko-bot@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > - [Low] Incorrect assertion failure message tag for invalid `addrs` pointer test. > -- > > commit edec3b6e703fee4df106f0b3f019e87b22c606fc > Author: Jiri Olsa <jolsa@kernel.org> > > selftests/bpf: Add tracing_multi link info tests > > This commit adds new tests for tracing_multi link info. The tests follow the > existing logic used for kprobe_multi and uprobe_multi tests. > > > diff --git a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > > index f589eefbf9fbd..969f04ee9ac6a 100644 > > --- a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > > +++ b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > > [ ... ] > > > +static void verify_tracing_multi_invalid_user_buffer(int fd, const struct tmulti_target *targets) > > +{ > > + __u32 ids[TRACING_MULTI_CNT] = {}; > > + struct bpf_link_info info; > > + __u32 len = sizeof(info); > > + int err, i; > > [ ... ] > > > + /* Invalid cookies pointer -> EFAULT */ > > + memset(&info, 0, sizeof(info)); > > + info.tracing_multi.cookies = 0x1; > > + info.tracing_multi.count = TRACING_MULTI_CNT; > > + err = bpf_link_get_info_by_fd(fd, &info, &len); > > + ASSERT_EQ(err, -EFAULT, "tracing_multi.bad_cookies"); > > + > > + /* Invalid addrs pointer -> EFAULT */ > > + memset(&info, 0, sizeof(info)); > > + info.tracing_multi.addrs = 0x1; > > + info.tracing_multi.count = TRACING_MULTI_CNT; > > + err = bpf_link_get_info_by_fd(fd, &info, &len); > > + ASSERT_EQ(err, -EFAULT, "tracing_multi.bad_cookies"); > > [Severity: Low] > This isn't a bug, but is this tag a copy-paste error? The comment mentions > testing an invalid addrs pointer, but the assertion in > verify_tracing_multi_invalid_user_buffer() uses the > "tracing_multi.bad_cookies" tag rather than something like > "tracing_multi.bad_addrs". yep, will fix jirka ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 2/3] selftests/bpf: Add tracing_multi link info tests 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-22 10:36 ` Jiri Olsa 1 sibling, 1 reply; 10+ messages in thread From: bot+bpf-ci @ 2026-06-21 21:31 UTC (permalink / raw) To: jolsa, ast, daniel, andrii Cc: bpf, martin.lau, eddyz87, songliubraving, yhs, qmo, ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai [-- Attachment #1: Type: text/plain, Size: 2277 bytes --] > diff --git a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > index f589eefbf9fb..969f04ee9ac6 100644 > --- a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > +++ b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c [ ... ] > @@ -396,6 +413,224 @@ static void test_kprobe_multi_fill_link_info(struct test_fill_link_info *skel, > bpf_link__destroy(link); > } > > +static void verify_tracing_multi_invalid_user_buffer(int fd, const struct tmulti_target *targets) > +{ > + __u32 ids[TRACING_MULTI_CNT] = {}; > + struct bpf_link_info info; > + __u32 len = sizeof(info); > + int err, i; > + > + /* Wrong info setup (ids != NULL and cnt == 0) -> EINVAL */ > + memset(&info, 0, sizeof(info)); > + info.tracing_multi.ids = ptr_to_u64(ids); > + err = bpf_link_get_info_by_fd(fd, &info, &len); > + ASSERT_EQ(err, -EINVAL, "tracing_multi.invalid_count"); > + > + /* Smaller than actuall count provided -> ENOSPC */ This isn't a bug, but "actuall" is misspelled here (should be "actual"). > + memset(ids, 0, sizeof(ids)); > + memset(&info, 0, sizeof(info)); > + info.tracing_multi.ids = ptr_to_u64(ids); > + info.tracing_multi.count = TRACING_MULTI_CNT - 1; > + err = bpf_link_get_info_by_fd(fd, &info, &len); > + ASSERT_EQ(err, -ENOSPC, "tracing_multi.small_count"); > + for (i = 0; i < TRACING_MULTI_CNT - 1; i++) > + ASSERT_EQ(ids[i], targets[i].id, "tracing_multi.partial_ids"); > + /* check that the last entry is not populated */ > + ASSERT_EQ(ids[i], 0, "tracing_multi.partial_ids"); > + > + /* Bigger than actuall count provided -> OK */ The same typo appears here. > + memset(ids, 0, sizeof(ids)); > + memset(&info, 0, sizeof(info)); > + info.tracing_multi.ids = ptr_to_u64(ids); > + info.tracing_multi.count = TRACING_MULTI_CNT + 1; > + err = bpf_link_get_info_by_fd(fd, &info, &len); > + ASSERT_OK(err, "tracing_multi.big_count"); > + for (i = 0; i < TRACING_MULTI_CNT; i++) > + ASSERT_EQ(ids[i], targets[i].id, "tracing_multi.ids"); [ ... ] --- AI reviewed your patch. Please fix the bug or email reply why it's not a bug. See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27917285330 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 2/3] selftests/bpf: Add tracing_multi link info tests 2026-06-21 21:31 ` bot+bpf-ci @ 2026-06-22 10:36 ` Jiri Olsa 0 siblings, 0 replies; 10+ messages in thread From: Jiri Olsa @ 2026-06-22 10:36 UTC (permalink / raw) To: bot+bpf-ci Cc: ast, daniel, andrii, bpf, martin.lau, eddyz87, songliubraving, yhs, qmo, martin.lau, yonghong.song, clm, ihor.solodrai On Sun, Jun 21, 2026 at 09:31:45PM +0000, bot+bpf-ci@kernel.org wrote: > > diff --git a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > > index f589eefbf9fb..969f04ee9ac6 100644 > > --- a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > > +++ b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c > > [ ... ] > > > @@ -396,6 +413,224 @@ static void test_kprobe_multi_fill_link_info(struct test_fill_link_info *skel, > > bpf_link__destroy(link); > > } > > > > +static void verify_tracing_multi_invalid_user_buffer(int fd, const struct tmulti_target *targets) > > +{ > > + __u32 ids[TRACING_MULTI_CNT] = {}; > > + struct bpf_link_info info; > > + __u32 len = sizeof(info); > > + int err, i; > > + > > + /* Wrong info setup (ids != NULL and cnt == 0) -> EINVAL */ > > + memset(&info, 0, sizeof(info)); > > + info.tracing_multi.ids = ptr_to_u64(ids); > > + err = bpf_link_get_info_by_fd(fd, &info, &len); > > + ASSERT_EQ(err, -EINVAL, "tracing_multi.invalid_count"); > > + > > + /* Smaller than actuall count provided -> ENOSPC */ > > This isn't a bug, but "actuall" is misspelled here (should be "actual"). > > > + memset(ids, 0, sizeof(ids)); > > + memset(&info, 0, sizeof(info)); > > + info.tracing_multi.ids = ptr_to_u64(ids); > > + info.tracing_multi.count = TRACING_MULTI_CNT - 1; > > + err = bpf_link_get_info_by_fd(fd, &info, &len); > > + ASSERT_EQ(err, -ENOSPC, "tracing_multi.small_count"); > > + for (i = 0; i < TRACING_MULTI_CNT - 1; i++) > > + ASSERT_EQ(ids[i], targets[i].id, "tracing_multi.partial_ids"); > > + /* check that the last entry is not populated */ > > + ASSERT_EQ(ids[i], 0, "tracing_multi.partial_ids"); > > + > > + /* Bigger than actuall count provided -> OK */ > > The same typo appears here. yep, will fix both jirka > > > + memset(ids, 0, sizeof(ids)); > > + memset(&info, 0, sizeof(info)); > > + info.tracing_multi.ids = ptr_to_u64(ids); > > + info.tracing_multi.count = TRACING_MULTI_CNT + 1; > > + err = bpf_link_get_info_by_fd(fd, &info, &len); > > + ASSERT_OK(err, "tracing_multi.big_count"); > > + for (i = 0; i < TRACING_MULTI_CNT; i++) > > + ASSERT_EQ(ids[i], targets[i].id, "tracing_multi.ids"); > > [ ... ] > > > --- > AI reviewed your patch. Please fix the bug or email reply why it's not a bug. > See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md > > CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27917285330 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH bpf-next 3/3] bpftool: Add tracing_multi link info output 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:45 ` Jiri Olsa 2026-06-21 20:56 ` sashiko-bot 2 siblings, 1 reply; 10+ messages in thread From: Jiri Olsa @ 2026-06-21 20:45 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko Cc: bpf, Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song, Quentin Monnet 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 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 3/3] bpftool: Add tracing_multi link info output 2026-06-21 20:45 ` [PATCH bpf-next 3/3] bpftool: Add tracing_multi link info output Jiri Olsa @ 2026-06-21 20:56 ` sashiko-bot 2026-06-22 10:35 ` Jiri Olsa 0 siblings, 1 reply; 10+ messages in thread From: sashiko-bot @ 2026-06-21 20:56 UTC (permalink / raw) To: Jiri Olsa; +Cc: bpf Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] Repeated parsing of `/proc/kallsyms` in an O(N) loop when symbol loading fails. -- commit 0f11f8e705a95b6aa483a05374ffb9b22bcb78c0 Author: Jiri Olsa <jolsa@kernel.org> bpftool: Add tracing_multi link info output This commit adds bpftool support to show tracing_multi link details for both plain and JSON outputs. > diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c > index bdcd717b0348f..58dadee984a07 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; > +} [ ... ] > @@ -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); [Severity: Medium] If kernel_syms_load() fails (for example, due to kernel.kptr_restrict or a lack of read permissions for /proc/kallsyms), dd.sym_count remains 0. Since find_kernel_sym_by_addr() checks !dd.sym_count to decide whether to load symbols, won't this cause /proc/kallsyms to be repeatedly opened and parsed on every iteration of this loop if the initial load fails? This loop occurs here in show_tracing_multi_json() as well as in show_tracing_multi_plain(). For tracing_multi links with potentially thousands of targets, could this result in a significant performance hang for bpftool? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260621204524.61067-1-jolsa@kernel.org?part=3 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 3/3] bpftool: Add tracing_multi link info output 2026-06-21 20:56 ` sashiko-bot @ 2026-06-22 10:35 ` Jiri Olsa 0 siblings, 0 replies; 10+ messages in thread From: Jiri Olsa @ 2026-06-22 10:35 UTC (permalink / raw) To: sashiko-reviews; +Cc: bpf On Sun, Jun 21, 2026 at 08:56:27PM +0000, sashiko-bot@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > - [Medium] Repeated parsing of `/proc/kallsyms` in an O(N) loop when symbol loading fails. > -- > > commit 0f11f8e705a95b6aa483a05374ffb9b22bcb78c0 > Author: Jiri Olsa <jolsa@kernel.org> > > bpftool: Add tracing_multi link info output > > This commit adds bpftool support to show tracing_multi link details for both > plain and JSON outputs. > > > diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c > > index bdcd717b0348f..58dadee984a07 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; > > +} > > [ ... ] > > > @@ -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); > > [Severity: Medium] > If kernel_syms_load() fails (for example, due to kernel.kptr_restrict or > a lack of read permissions for /proc/kallsyms), dd.sym_count remains 0. > > Since find_kernel_sym_by_addr() checks !dd.sym_count to decide whether to load > symbols, won't this cause /proc/kallsyms to be repeatedly opened and parsed on > every iteration of this loop if the initial load fails? > > This loop occurs here in show_tracing_multi_json() as well as in > show_tracing_multi_plain(). For tracing_multi links with potentially thousands > of targets, could this result in a significant performance hang for bpftool? ok, I think we can make sure the parsing happens just once with the change below, will do that in next version jirka --- diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c index 58dadee984a0..db780ee39820 100644 --- a/tools/bpf/bpftool/link.c +++ b/tools/bpf/bpftool/link.c @@ -389,12 +389,6 @@ static struct kernel_sym *find_kernel_sym_by_addr(__u64 addr, bool is_ibt_enable 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); @@ -431,9 +425,13 @@ show_uprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr) static void show_tracing_multi_json(struct bpf_link_info *info, json_writer_t *wtr) { - bool is_ibt_enabled = is_x86_ibt_enabled(); + bool is_ibt_enabled = is_x86_ibt_enabled(), show_symbol; __u32 i; + if (!dd.sym_count) + kernel_syms_load(&dd); + show_symbol = !!dd.sym_count; + 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); @@ -445,7 +443,7 @@ show_tracing_multi_json(struct bpf_link_info *info, json_writer_t *wtr) __u64 addr = u64_to_arr(info->tracing_multi.addrs)[i]; struct kernel_sym *sym; - sym = find_kernel_sym_by_addr(addr, is_ibt_enabled); + sym = show_symbol ? find_kernel_sym_by_addr(addr, is_ibt_enabled) : NULL; jsonw_start_object(wtr); jsonw_uint_field(wtr, "id", u64_to_u32_arr(info->tracing_multi.ids)[i]); @@ -900,12 +898,16 @@ 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(); + bool is_ibt_enabled = is_x86_ibt_enabled(), show_symbol; __u32 i; if (!info->tracing_multi.count) return; + if (!dd.sym_count) + kernel_syms_load(&dd); + show_symbol = !!dd.sym_count; + printf("\n\t"); show_link_attach_type_plain(info->tracing_multi.attach_type); printf("obj_id %u ", info->tracing_multi.obj_id); @@ -917,7 +919,7 @@ static void show_tracing_multi_plain(struct bpf_link_info *info) __u64 addr = u64_to_arr(info->tracing_multi.addrs)[i]; struct kernel_sym *sym; - sym = find_kernel_sym_by_addr(addr, is_ibt_enabled); + sym = show_symbol ? find_kernel_sym_by_addr(addr, is_ibt_enabled) : NULL; printf("\n\t%-16u %016llx %-16llx", u64_to_u32_arr(info->tracing_multi.ids)[i], ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-06-22 10:36 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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-22 10:35 ` Jiri Olsa 2026-06-21 21:31 ` bot+bpf-ci 2026-06-22 10:36 ` Jiri Olsa 2026-06-21 20:45 ` [PATCH bpf-next 3/3] bpftool: Add tracing_multi link info output Jiri Olsa 2026-06-21 20:56 ` sashiko-bot 2026-06-22 10:35 ` Jiri Olsa
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.