mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 11:03:07 -04:00
bpftool: Add tracing_multi link info output
Adding bpftool support to show tracing_multi link details,
the new output looks like:
# bpftool link
...
61: tracing_multi prog 167
attach_type trace_fentry_multi btf_obj_id 1 count 3
btf_id addr cookie func [module]
92598 ffffffff825017c4 10 bpf_fentry_test1
92600 ffffffff82503814 30 bpf_fentry_test2
92601 ffffffff82503824 20 bpf_fentry_test3
pids test_progs(1540)
Assisted-by: Codex:GPT-5
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260629212208.895962-4-jolsa@kernel.org
This commit is contained in:
committed by
Andrii Nakryiko
parent
d36e4dd547
commit
37c1e353c9
@@ -377,6 +377,25 @@ 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;
|
||||
|
||||
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 +422,52 @@ 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(), show_symbol;
|
||||
__u64 *addrs, *cookies;
|
||||
__u32 i, *ids;
|
||||
|
||||
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, "btf_obj_id", info->tracing_multi.btf_obj_id);
|
||||
jsonw_name(wtr, "funcs");
|
||||
|
||||
jsonw_start_array(wtr);
|
||||
|
||||
ids = u64_to_u32_arr(info->tracing_multi.ids);
|
||||
addrs = u64_to_arr(info->tracing_multi.addrs);
|
||||
cookies = u64_to_arr(info->tracing_multi.cookies);
|
||||
|
||||
for (i = 0; i < info->tracing_multi.count; i++) {
|
||||
struct kernel_sym *sym;
|
||||
__u64 addr = addrs[i];
|
||||
|
||||
sym = show_symbol ? find_kernel_sym_by_addr(addr, is_ibt_enabled) : NULL;
|
||||
|
||||
jsonw_start_object(wtr);
|
||||
jsonw_uint_field(wtr, "id", 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", 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 +654,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 +901,46 @@ 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(), show_symbol;
|
||||
__u64 *addrs, *cookies;
|
||||
__u32 i, *ids;
|
||||
|
||||
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("btf_obj_id %u ", info->tracing_multi.btf_obj_id);
|
||||
printf("count %u ", info->tracing_multi.count);
|
||||
|
||||
printf("\n\t%-16s %-16s %-16s %s",
|
||||
"btf_id", "addr", "cookie", "func [module]");
|
||||
|
||||
ids = u64_to_u32_arr(info->tracing_multi.ids);
|
||||
addrs = u64_to_arr(info->tracing_multi.addrs);
|
||||
cookies = u64_to_arr(info->tracing_multi.cookies);
|
||||
|
||||
for (i = 0; i < info->tracing_multi.count; i++) {
|
||||
__u64 addr = addrs[i];
|
||||
struct kernel_sym *sym;
|
||||
|
||||
sym = show_symbol ? find_kernel_sym_by_addr(addr, is_ibt_enabled) : NULL;
|
||||
|
||||
printf("\n\t%-16u %016llx %-16llu", ids[i], addr, 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 +1097,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 +1140,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 +1226,26 @@ 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));
|
||||
addrs = calloc(count, sizeof(__u64));
|
||||
cookies = calloc(count, sizeof(__u64));
|
||||
if (!ids || !addrs || !cookies) {
|
||||
p_err("mem alloc failed");
|
||||
close(fd);
|
||||
free(cookies);
|
||||
free(addrs);
|
||||
free(ids);
|
||||
return -ENOMEM;
|
||||
}
|
||||
info.tracing_multi.ids = ptr_to_u64(ids);
|
||||
info.tracing_multi.addrs = ptr_to_u64(addrs);
|
||||
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 +1285,7 @@ static int do_show_link(int fd)
|
||||
free(cookies);
|
||||
free(offsets);
|
||||
free(addrs);
|
||||
free(ids);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user