diff mbox series

[v3,bpf-next,03/10] bpftool: Show probed function in kprobe_multi link info

Message ID 20230612151608.99661-4-laoar.shao@gmail.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series bpf: Support ->fill_link_info for kprobe_multi and perf_event links | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/cc_maintainers success CCed 13 of 13 maintainers
netdev/build_clang success Errors and warnings before: 8 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch warning WARNING: line length of 81 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-29 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-11 fail Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 fail Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 fail Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 fail Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 fail Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 fail Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 fail Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ${{ matrix.test }} on ${{ matrix.arch }} with ${{ matrix.toolchain_full }}
bpf/vmtest-bpf-next-VM_Test-2 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 fail Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-7 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-8 success Logs for veristat

Commit Message

Yafang Shao June 12, 2023, 3:16 p.m. UTC
Show the already expose kprobe_multi link info in bpftool. The result as
follows,

52: kprobe_multi  prog 381
        retprobe 0  func_cnt 7
        addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
              ffffffff9ec44f60        schedule_timeout_killable
              ffffffff9ec44fa0        schedule_timeout_uninterruptible
              ffffffff9ec44fe0        schedule_timeout_idle
              ffffffffc09468d0        xfs_trans_get_efd [xfs]
              ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
              ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
        pids kprobe_multi(559862)
53: kprobe_multi  prog 381
        retprobe 1  func_cnt 7
        addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
              ffffffff9ec44f60        schedule_timeout_killable
              ffffffff9ec44fa0        schedule_timeout_uninterruptible
              ffffffff9ec44fe0        schedule_timeout_idle
              ffffffffc09468d0        xfs_trans_get_efd [xfs]
              ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
              ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
        pids kprobe_multi(559862)

$ tools/bpf/bpftool/bpftool link show -j
[{"id":52,"type":"kprobe_multi","prog_id":381,"retprobe":0,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]},{"id":53,"type":"kprobe_multi","prog_id":381,"retprobe":1,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]}]

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 tools/bpf/bpftool/link.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 108 insertions(+), 1 deletion(-)

Comments

Quentin Monnet June 13, 2023, 1:41 p.m. UTC | #1
2023-06-12 15:16 UTC+0000 ~ Yafang Shao <laoar.shao@gmail.com>
> Show the already expose kprobe_multi link info in bpftool. The result as
> follows,
> 
> 52: kprobe_multi  prog 381
>         retprobe 0  func_cnt 7
>         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
>               ffffffff9ec44f60        schedule_timeout_killable
>               ffffffff9ec44fa0        schedule_timeout_uninterruptible
>               ffffffff9ec44fe0        schedule_timeout_idle
>               ffffffffc09468d0        xfs_trans_get_efd [xfs]
>               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
>               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
>         pids kprobe_multi(559862)
> 53: kprobe_multi  prog 381
>         retprobe 1  func_cnt 7
>         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
>               ffffffff9ec44f60        schedule_timeout_killable
>               ffffffff9ec44fa0        schedule_timeout_uninterruptible
>               ffffffff9ec44fe0        schedule_timeout_idle
>               ffffffffc09468d0        xfs_trans_get_efd [xfs]
>               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
>               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
>         pids kprobe_multi(559862)
> 
> $ tools/bpf/bpftool/bpftool link show -j
> [{"id":52,"type":"kprobe_multi","prog_id":381,"retprobe":0,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]},{"id":53,"type":"kprobe_multi","prog_id":381,"retprobe":1,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]}]
> 
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> ---
>  tools/bpf/bpftool/link.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 108 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
> index 2d78607..0015582 100644
> --- a/tools/bpf/bpftool/link.c
> +++ b/tools/bpf/bpftool/link.c
> @@ -14,8 +14,10 @@
>  
>  #include "json_writer.h"
>  #include "main.h"
> +#include "xlated_dumper.h"
>  
>  static struct hashmap *link_table;
> +static struct dump_data dd = {};
>  
>  static int link_parse_fd(int *argc, char ***argv)
>  {
> @@ -166,6 +168,45 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)
>  	return err;
>  }
>  
> +static int cmp_u64(const void *A, const void *B)
> +{
> +	const __u64 *a = A, *b = B;
> +
> +	return *a - *b;
> +}
> +
> +static void
> +show_kprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
> +{
> +	__u32 i, j = 0;
> +	__u64 *addrs;
> +
> +	jsonw_uint_field(json_wtr, "retprobe",
> +			 info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN);

The "retprobe" field could maybe be a boolean rather than an int.

> +	jsonw_uint_field(json_wtr, "func_cnt", info->kprobe_multi.count);
> +	jsonw_name(json_wtr, "funcs");
> +	jsonw_start_array(json_wtr);
> +	addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
> +	qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
> +
> +	/* Load it once for all. */
> +	if (!dd.sym_count)
> +		kernel_syms_load(&dd);
> +	for (i = 0; i < dd.sym_count; i++) {
> +		if (dd.sym_mapping[i].address != addrs[j])
> +			continue;
> +		jsonw_start_object(json_wtr);
> +		jsonw_uint_field(json_wtr, "addr", dd.sym_mapping[i].address);
> +		jsonw_string_field(json_wtr, "func", dd.sym_mapping[i].name);
> +		/* Print none if it is vmlinux */
> +		jsonw_string_field(json_wtr, "module", dd.sym_mapping[i].module);

Can we trim the square brackets around module names for the JSON output,
please? They make entries look like arrays; but mostly, if we keep them,
we're forcing every consumer to trim them on their side before being
able to reuse the value.
Yafang Shao June 13, 2023, 2:59 p.m. UTC | #2
On Tue, Jun 13, 2023 at 9:41 PM Quentin Monnet <quentin@isovalent.com> wrote:
>
> 2023-06-12 15:16 UTC+0000 ~ Yafang Shao <laoar.shao@gmail.com>
> > Show the already expose kprobe_multi link info in bpftool. The result as
> > follows,
> >
> > 52: kprobe_multi  prog 381
> >         retprobe 0  func_cnt 7
> >         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> >               ffffffff9ec44f60        schedule_timeout_killable
> >               ffffffff9ec44fa0        schedule_timeout_uninterruptible
> >               ffffffff9ec44fe0        schedule_timeout_idle
> >               ffffffffc09468d0        xfs_trans_get_efd [xfs]
> >               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> >               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
> >         pids kprobe_multi(559862)
> > 53: kprobe_multi  prog 381
> >         retprobe 1  func_cnt 7
> >         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> >               ffffffff9ec44f60        schedule_timeout_killable
> >               ffffffff9ec44fa0        schedule_timeout_uninterruptible
> >               ffffffff9ec44fe0        schedule_timeout_idle
> >               ffffffffc09468d0        xfs_trans_get_efd [xfs]
> >               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> >               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
> >         pids kprobe_multi(559862)
> >
> > $ tools/bpf/bpftool/bpftool link show -j
> > [{"id":52,"type":"kprobe_multi","prog_id":381,"retprobe":0,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]},{"id":53,"type":"kprobe_multi","prog_id":381,"retprobe":1,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]}]
> >
> > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > ---
> >  tools/bpf/bpftool/link.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 108 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
> > index 2d78607..0015582 100644
> > --- a/tools/bpf/bpftool/link.c
> > +++ b/tools/bpf/bpftool/link.c
> > @@ -14,8 +14,10 @@
> >
> >  #include "json_writer.h"
> >  #include "main.h"
> > +#include "xlated_dumper.h"
> >
> >  static struct hashmap *link_table;
> > +static struct dump_data dd = {};
> >
> >  static int link_parse_fd(int *argc, char ***argv)
> >  {
> > @@ -166,6 +168,45 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)
> >       return err;
> >  }
> >
> > +static int cmp_u64(const void *A, const void *B)
> > +{
> > +     const __u64 *a = A, *b = B;
> > +
> > +     return *a - *b;
> > +}
> > +
> > +static void
> > +show_kprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
> > +{
> > +     __u32 i, j = 0;
> > +     __u64 *addrs;
> > +
> > +     jsonw_uint_field(json_wtr, "retprobe",
> > +                      info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN);
>
> The "retprobe" field could maybe be a boolean rather than an int.

Will change it.

>
> > +     jsonw_uint_field(json_wtr, "func_cnt", info->kprobe_multi.count);
> > +     jsonw_name(json_wtr, "funcs");
> > +     jsonw_start_array(json_wtr);
> > +     addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
> > +     qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
> > +
> > +     /* Load it once for all. */
> > +     if (!dd.sym_count)
> > +             kernel_syms_load(&dd);
> > +     for (i = 0; i < dd.sym_count; i++) {
> > +             if (dd.sym_mapping[i].address != addrs[j])
> > +                     continue;
> > +             jsonw_start_object(json_wtr);
> > +             jsonw_uint_field(json_wtr, "addr", dd.sym_mapping[i].address);
> > +             jsonw_string_field(json_wtr, "func", dd.sym_mapping[i].name);
> > +             /* Print none if it is vmlinux */
> > +             jsonw_string_field(json_wtr, "module", dd.sym_mapping[i].module);
>
> Can we trim the square brackets around module names for the JSON output,
> please? They make entries look like arrays; but mostly, if we keep them,
> we're forcing every consumer to trim them on their side before being
> able to reuse the value.

Agree, will trim it.
Kui-Feng Lee June 13, 2023, 10:36 p.m. UTC | #3
On 6/12/23 08:16, Yafang Shao wrote:
> Show the already expose kprobe_multi link info in bpftool. The result as
> follows,
> 
> 52: kprobe_multi  prog 381
>          retprobe 0  func_cnt 7
>          addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
>                ffffffff9ec44f60        schedule_timeout_killable
>                ffffffff9ec44fa0        schedule_timeout_uninterruptible
>                ffffffff9ec44fe0        schedule_timeout_idle
>                ffffffffc09468d0        xfs_trans_get_efd [xfs]
>                ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
>                ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
>          pids kprobe_multi(559862)
> 53: kprobe_multi  prog 381
>          retprobe 1  func_cnt 7
>          addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
>                ffffffff9ec44f60        schedule_timeout_killable
>                ffffffff9ec44fa0        schedule_timeout_uninterruptible
>                ffffffff9ec44fe0        schedule_timeout_idle
>                ffffffffc09468d0        xfs_trans_get_efd [xfs]
>                ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
>                ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
>          pids kprobe_multi(559862)
> 
> $ tools/bpf/bpftool/bpftool link show -j
> [{"id":52,"type":"kprobe_multi","prog_id":381,"retprobe":0,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]},{"id":53,"type":"kprobe_multi","prog_id":381,"retprobe":1,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]}]
> 
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> ---
>   tools/bpf/bpftool/link.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 108 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
> index 2d78607..0015582 100644
> --- a/tools/bpf/bpftool/link.c
> +++ b/tools/bpf/bpftool/link.c
> @@ -14,8 +14,10 @@
>   
>   #include "json_writer.h"
>   #include "main.h"
> +#include "xlated_dumper.h"
>   
>   static struct hashmap *link_table;
> +static struct dump_data dd = {};
>   
>   static int link_parse_fd(int *argc, char ***argv)
>   {
> @@ -166,6 +168,45 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)
>   	return err;
>   }
>   
> +static int cmp_u64(const void *A, const void *B)
> +{
> +	const __u64 *a = A, *b = B;
> +
> +	return *a - *b;
> +}
> +
> +static void
> +show_kprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
> +{
> +	__u32 i, j = 0;
> +	__u64 *addrs;
> +
> +	jsonw_uint_field(json_wtr, "retprobe",
> +			 info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN);
> +	jsonw_uint_field(json_wtr, "func_cnt", info->kprobe_multi.count);
> +	jsonw_name(json_wtr, "funcs");
> +	jsonw_start_array(json_wtr);
> +	addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
> +	qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
> +
> +	/* Load it once for all. */
> +	if (!dd.sym_count)
> +		kernel_syms_load(&dd);
> +	for (i = 0; i < dd.sym_count; i++) {
> +		if (dd.sym_mapping[i].address != addrs[j])
> +			continue;
> +		jsonw_start_object(json_wtr);
> +		jsonw_uint_field(json_wtr, "addr", dd.sym_mapping[i].address);
> +		jsonw_string_field(json_wtr, "func", dd.sym_mapping[i].name);
> +		/* Print none if it is vmlinux */
> +		jsonw_string_field(json_wtr, "module", dd.sym_mapping[i].module);
> +		jsonw_end_object(json_wtr);
> +		if (j++ == info->kprobe_multi.count)
> +			break;
> +	}
> +	jsonw_end_array(json_wtr);
> +}
> +
>   static int show_link_close_json(int fd, struct bpf_link_info *info)
>   {
>   	struct bpf_prog_info prog_info;
> @@ -218,6 +259,9 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
>   		jsonw_uint_field(json_wtr, "map_id",
>   				 info->struct_ops.map_id);
>   		break;
> +	case BPF_LINK_TYPE_KPROBE_MULTI:
> +		show_kprobe_multi_json(info, json_wtr);
> +		break;
>   	default:
>   		break;
>   	}
> @@ -351,6 +395,44 @@ void netfilter_dump_plain(const struct bpf_link_info *info)
>   		printf(" flags 0x%x", info->netfilter.flags);
>   }
>   
> +static void show_kprobe_multi_plain(struct bpf_link_info *info)
> +{
> +	__u32 i, j = 0;
> +	__u64 *addrs;
> +
> +	if (!info->kprobe_multi.count)
> +		return;
> +
> +	printf("\n\tretprobe %d  func_cnt %u  ",
> +	       info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN,
> +	       info->kprobe_multi.count);
> +	addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
> +	qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
> +
> +	/* Load it once for all. */
> +	if (!dd.sym_count)
> +		kernel_syms_load(&dd);
> +	for (i = 0; i < dd.sym_count; i++) {
> +		if (dd.sym_mapping[i].address != addrs[j])
> +			continue;
> +		if (!j)
> +			printf("\n\taddrs %016lx  funcs %s",
> +			       dd.sym_mapping[i].address,
> +			       dd.sym_mapping[i].name);
> +		else
> +			printf("\n\t      %016lx        %s",
> +			       dd.sym_mapping[i].address,
> +			       dd.sym_mapping[i].name);
> +		if (dd.sym_mapping[i].module[0] != '\0')
> +			printf(" %s  ", dd.sym_mapping[i].module);
> +		else
> +			printf("  ");

Could you explain what these extra spaces after module names are for?

> +
> +		if (j++ == info->kprobe_multi.count)
> +			break;
> +	}
> +}
> +
>   static int show_link_close_plain(int fd, struct bpf_link_info *info)
>   {
>   	struct bpf_prog_info prog_info;
> @@ -396,6 +478,9 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info)
>   	case BPF_LINK_TYPE_NETFILTER:
>   		netfilter_dump_plain(info);
>   		break;
> +	case BPF_LINK_TYPE_KPROBE_MULTI:
> +		show_kprobe_multi_plain(info);
> +		break;
>   	default:
>   		break;
>   	}
> @@ -417,7 +502,9 @@ static int do_show_link(int fd)
>   {
>   	struct bpf_link_info info;
>   	__u32 len = sizeof(info);
> +	__u64 *addrs = NULL;
>   	char buf[256];
> +	int count;
>   	int err;
>   
>   	memset(&info, 0, sizeof(info));
> @@ -441,12 +528,28 @@ static int do_show_link(int fd)
>   		info.iter.target_name_len = sizeof(buf);
>   		goto again;
>   	}
> +	if (info.type == BPF_LINK_TYPE_KPROBE_MULTI &&
> +	    !info.kprobe_multi.addrs) {
> +		count = info.kprobe_multi.count;
> +		if (count) {
> +			addrs = calloc(count, sizeof(__u64));
> +			if (!addrs) {
> +				p_err("mem alloc failed");
> +				close(fd);
> +				return -1;
> +			}
> +			info.kprobe_multi.addrs = (unsigned long)addrs;
> +			goto again;
> +		}
> +	}
>   
>   	if (json_output)
>   		show_link_close_json(fd, &info);
>   	else
>   		show_link_close_plain(fd, &info);
>   
> +	if (addrs)
> +		free(addrs);
>   	close(fd);
>   	return 0;
>   }
> @@ -471,7 +574,8 @@ static int do_show(int argc, char **argv)
>   		fd = link_parse_fd(&argc, &argv);
>   		if (fd < 0)
>   			return fd;
> -		return do_show_link(fd);
> +		do_show_link(fd);
> +		goto out;
>   	}
>   
>   	if (argc)
> @@ -510,6 +614,9 @@ static int do_show(int argc, char **argv)
>   	if (show_pinned)
>   		delete_pinned_obj_table(link_table);
>   
> +out:
> +	if (dd.sym_count)
> +		kernel_syms_destroy(&dd);
>   	return errno == ENOENT ? 0 : -1;
>   }
>
Yafang Shao June 14, 2023, 2:42 a.m. UTC | #4
On Wed, Jun 14, 2023 at 6:36 AM Kui-Feng Lee <sinquersw@gmail.com> wrote:
>
>
>
> On 6/12/23 08:16, Yafang Shao wrote:
> > Show the already expose kprobe_multi link info in bpftool. The result as
> > follows,
> >
> > 52: kprobe_multi  prog 381
> >          retprobe 0  func_cnt 7
> >          addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> >                ffffffff9ec44f60        schedule_timeout_killable
> >                ffffffff9ec44fa0        schedule_timeout_uninterruptible
> >                ffffffff9ec44fe0        schedule_timeout_idle
> >                ffffffffc09468d0        xfs_trans_get_efd [xfs]
> >                ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> >                ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
> >          pids kprobe_multi(559862)
> > 53: kprobe_multi  prog 381
> >          retprobe 1  func_cnt 7
> >          addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> >                ffffffff9ec44f60        schedule_timeout_killable
> >                ffffffff9ec44fa0        schedule_timeout_uninterruptible
> >                ffffffff9ec44fe0        schedule_timeout_idle
> >                ffffffffc09468d0        xfs_trans_get_efd [xfs]
> >                ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> >                ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
> >          pids kprobe_multi(559862)
> >
> > $ tools/bpf/bpftool/bpftool link show -j
> > [{"id":52,"type":"kprobe_multi","prog_id":381,"retprobe":0,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]},{"id":53,"type":"kprobe_multi","prog_id":381,"retprobe":1,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]}]
> >
> > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > ---
> >   tools/bpf/bpftool/link.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-
> >   1 file changed, 108 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
> > index 2d78607..0015582 100644
> > --- a/tools/bpf/bpftool/link.c
> > +++ b/tools/bpf/bpftool/link.c
> > @@ -14,8 +14,10 @@
> >
> >   #include "json_writer.h"
> >   #include "main.h"
> > +#include "xlated_dumper.h"
> >
> >   static struct hashmap *link_table;
> > +static struct dump_data dd = {};
> >
> >   static int link_parse_fd(int *argc, char ***argv)
> >   {
> > @@ -166,6 +168,45 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)
> >       return err;
> >   }
> >
> > +static int cmp_u64(const void *A, const void *B)
> > +{
> > +     const __u64 *a = A, *b = B;
> > +
> > +     return *a - *b;
> > +}
> > +
> > +static void
> > +show_kprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
> > +{
> > +     __u32 i, j = 0;
> > +     __u64 *addrs;
> > +
> > +     jsonw_uint_field(json_wtr, "retprobe",
> > +                      info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN);
> > +     jsonw_uint_field(json_wtr, "func_cnt", info->kprobe_multi.count);
> > +     jsonw_name(json_wtr, "funcs");
> > +     jsonw_start_array(json_wtr);
> > +     addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
> > +     qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
> > +
> > +     /* Load it once for all. */
> > +     if (!dd.sym_count)
> > +             kernel_syms_load(&dd);
> > +     for (i = 0; i < dd.sym_count; i++) {
> > +             if (dd.sym_mapping[i].address != addrs[j])
> > +                     continue;
> > +             jsonw_start_object(json_wtr);
> > +             jsonw_uint_field(json_wtr, "addr", dd.sym_mapping[i].address);
> > +             jsonw_string_field(json_wtr, "func", dd.sym_mapping[i].name);
> > +             /* Print none if it is vmlinux */
> > +             jsonw_string_field(json_wtr, "module", dd.sym_mapping[i].module);
> > +             jsonw_end_object(json_wtr);
> > +             if (j++ == info->kprobe_multi.count)
> > +                     break;
> > +     }
> > +     jsonw_end_array(json_wtr);
> > +}
> > +
> >   static int show_link_close_json(int fd, struct bpf_link_info *info)
> >   {
> >       struct bpf_prog_info prog_info;
> > @@ -218,6 +259,9 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
> >               jsonw_uint_field(json_wtr, "map_id",
> >                                info->struct_ops.map_id);
> >               break;
> > +     case BPF_LINK_TYPE_KPROBE_MULTI:
> > +             show_kprobe_multi_json(info, json_wtr);
> > +             break;
> >       default:
> >               break;
> >       }
> > @@ -351,6 +395,44 @@ void netfilter_dump_plain(const struct bpf_link_info *info)
> >               printf(" flags 0x%x", info->netfilter.flags);
> >   }
> >
> > +static void show_kprobe_multi_plain(struct bpf_link_info *info)
> > +{
> > +     __u32 i, j = 0;
> > +     __u64 *addrs;
> > +
> > +     if (!info->kprobe_multi.count)
> > +             return;
> > +
> > +     printf("\n\tretprobe %d  func_cnt %u  ",
> > +            info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN,
> > +            info->kprobe_multi.count);
> > +     addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
> > +     qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
> > +
> > +     /* Load it once for all. */
> > +     if (!dd.sym_count)
> > +             kernel_syms_load(&dd);
> > +     for (i = 0; i < dd.sym_count; i++) {
> > +             if (dd.sym_mapping[i].address != addrs[j])
> > +                     continue;
> > +             if (!j)
> > +                     printf("\n\taddrs %016lx  funcs %s",
> > +                            dd.sym_mapping[i].address,
> > +                            dd.sym_mapping[i].name);
> > +             else
> > +                     printf("\n\t      %016lx        %s",
> > +                            dd.sym_mapping[i].address,
> > +                            dd.sym_mapping[i].name);
> > +             if (dd.sym_mapping[i].module[0] != '\0')
> > +                     printf(" %s  ", dd.sym_mapping[i].module);
> > +             else
> > +                     printf("  ");
>
> Could you explain what these extra spaces after module names are for?

There are two spaces. We use two spaces to seperate different items
printed in bpftool. For example,
  "4: kprobe_multi  prog 16"
There are two spaces between the "type" and the "prog".

We always print these two spaces after one item is printed:
  printf("type %u  ", info->type);
  printf("prog %u  ", info->prog_id);
That way, we can add new item easily and consistently.
Quentin Monnet June 14, 2023, 8:33 a.m. UTC | #5
2023-06-14 10:42 UTC+0800 ~ Yafang Shao <laoar.shao@gmail.com>
> On Wed, Jun 14, 2023 at 6:36 AM Kui-Feng Lee <sinquersw@gmail.com> wrote:
>>
>>
>>
>> On 6/12/23 08:16, Yafang Shao wrote:
>>> Show the already expose kprobe_multi link info in bpftool. The result as
>>> follows,
>>>
>>> 52: kprobe_multi  prog 381
>>>          retprobe 0  func_cnt 7
>>>          addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
>>>                ffffffff9ec44f60        schedule_timeout_killable
>>>                ffffffff9ec44fa0        schedule_timeout_uninterruptible
>>>                ffffffff9ec44fe0        schedule_timeout_idle
>>>                ffffffffc09468d0        xfs_trans_get_efd [xfs]
>>>                ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
>>>                ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
>>>          pids kprobe_multi(559862)
>>> 53: kprobe_multi  prog 381
>>>          retprobe 1  func_cnt 7
>>>          addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
>>>                ffffffff9ec44f60        schedule_timeout_killable
>>>                ffffffff9ec44fa0        schedule_timeout_uninterruptible
>>>                ffffffff9ec44fe0        schedule_timeout_idle
>>>                ffffffffc09468d0        xfs_trans_get_efd [xfs]
>>>                ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
>>>                ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
>>>          pids kprobe_multi(559862)
>>>
>>> $ tools/bpf/bpftool/bpftool link show -j
>>> [{"id":52,"type":"kprobe_multi","prog_id":381,"retprobe":0,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]},{"id":53,"type":"kprobe_multi","prog_id":381,"retprobe":1,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]}]
>>>
>>> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
>>> ---
>>>   tools/bpf/bpftool/link.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-
>>>   1 file changed, 108 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
>>> index 2d78607..0015582 100644
>>> --- a/tools/bpf/bpftool/link.c
>>> +++ b/tools/bpf/bpftool/link.c
>>> @@ -14,8 +14,10 @@
>>>
>>>   #include "json_writer.h"
>>>   #include "main.h"
>>> +#include "xlated_dumper.h"
>>>
>>>   static struct hashmap *link_table;
>>> +static struct dump_data dd = {};
>>>
>>>   static int link_parse_fd(int *argc, char ***argv)
>>>   {
>>> @@ -166,6 +168,45 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)
>>>       return err;
>>>   }
>>>
>>> +static int cmp_u64(const void *A, const void *B)
>>> +{
>>> +     const __u64 *a = A, *b = B;
>>> +
>>> +     return *a - *b;
>>> +}
>>> +
>>> +static void
>>> +show_kprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
>>> +{
>>> +     __u32 i, j = 0;
>>> +     __u64 *addrs;
>>> +
>>> +     jsonw_uint_field(json_wtr, "retprobe",
>>> +                      info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN);
>>> +     jsonw_uint_field(json_wtr, "func_cnt", info->kprobe_multi.count);
>>> +     jsonw_name(json_wtr, "funcs");
>>> +     jsonw_start_array(json_wtr);
>>> +     addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
>>> +     qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
>>> +
>>> +     /* Load it once for all. */
>>> +     if (!dd.sym_count)
>>> +             kernel_syms_load(&dd);
>>> +     for (i = 0; i < dd.sym_count; i++) {
>>> +             if (dd.sym_mapping[i].address != addrs[j])
>>> +                     continue;
>>> +             jsonw_start_object(json_wtr);
>>> +             jsonw_uint_field(json_wtr, "addr", dd.sym_mapping[i].address);
>>> +             jsonw_string_field(json_wtr, "func", dd.sym_mapping[i].name);
>>> +             /* Print none if it is vmlinux */
>>> +             jsonw_string_field(json_wtr, "module", dd.sym_mapping[i].module);
>>> +             jsonw_end_object(json_wtr);
>>> +             if (j++ == info->kprobe_multi.count)
>>> +                     break;
>>> +     }
>>> +     jsonw_end_array(json_wtr);
>>> +}
>>> +
>>>   static int show_link_close_json(int fd, struct bpf_link_info *info)
>>>   {
>>>       struct bpf_prog_info prog_info;
>>> @@ -218,6 +259,9 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
>>>               jsonw_uint_field(json_wtr, "map_id",
>>>                                info->struct_ops.map_id);
>>>               break;
>>> +     case BPF_LINK_TYPE_KPROBE_MULTI:
>>> +             show_kprobe_multi_json(info, json_wtr);
>>> +             break;
>>>       default:
>>>               break;
>>>       }
>>> @@ -351,6 +395,44 @@ void netfilter_dump_plain(const struct bpf_link_info *info)
>>>               printf(" flags 0x%x", info->netfilter.flags);
>>>   }
>>>
>>> +static void show_kprobe_multi_plain(struct bpf_link_info *info)
>>> +{
>>> +     __u32 i, j = 0;
>>> +     __u64 *addrs;
>>> +
>>> +     if (!info->kprobe_multi.count)
>>> +             return;
>>> +
>>> +     printf("\n\tretprobe %d  func_cnt %u  ",
>>> +            info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN,
>>> +            info->kprobe_multi.count);
>>> +     addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
>>> +     qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
>>> +
>>> +     /* Load it once for all. */
>>> +     if (!dd.sym_count)
>>> +             kernel_syms_load(&dd);
>>> +     for (i = 0; i < dd.sym_count; i++) {
>>> +             if (dd.sym_mapping[i].address != addrs[j])
>>> +                     continue;
>>> +             if (!j)
>>> +                     printf("\n\taddrs %016lx  funcs %s",
>>> +                            dd.sym_mapping[i].address,
>>> +                            dd.sym_mapping[i].name);
>>> +             else
>>> +                     printf("\n\t      %016lx        %s",
>>> +                            dd.sym_mapping[i].address,
>>> +                            dd.sym_mapping[i].name);
>>> +             if (dd.sym_mapping[i].module[0] != '\0')
>>> +                     printf(" %s  ", dd.sym_mapping[i].module);
>>> +             else
>>> +                     printf("  ");
>>
>> Could you explain what these extra spaces after module names are for?
> 
> There are two spaces. We use two spaces to seperate different items
> printed in bpftool. For example,
>   "4: kprobe_multi  prog 16"
> There are two spaces between the "type" and the "prog".
> 
> We always print these two spaces after one item is printed:
>   printf("type %u  ", info->type);
>   printf("prog %u  ", info->prog_id);
> That way, we can add new item easily and consistently.
> 

I'm not sure we _always_ do it at the end of lines, but it seems to be
rather consistent in link.c at least. For my part I don't know if this
printf("  ") is really necessary - I'd rather avoid spaces at the end of
lines, but then there would be several other locations to update. So I
don't have any objection, either.

Quentin
Andrii Nakryiko June 16, 2023, 5:30 p.m. UTC | #6
On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> Show the already expose kprobe_multi link info in bpftool. The result as
> follows,
>
> 52: kprobe_multi  prog 381
>         retprobe 0  func_cnt 7
>         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
>               ffffffff9ec44f60        schedule_timeout_killable
>               ffffffff9ec44fa0        schedule_timeout_uninterruptible
>               ffffffff9ec44fe0        schedule_timeout_idle
>               ffffffffc09468d0        xfs_trans_get_efd [xfs]
>               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
>               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
>         pids kprobe_multi(559862)
> 53: kprobe_multi  prog 381
>         retprobe 1  func_cnt 7
>         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
>               ffffffff9ec44f60        schedule_timeout_killable
>               ffffffff9ec44fa0        schedule_timeout_uninterruptible
>               ffffffff9ec44fe0        schedule_timeout_idle
>               ffffffffc09468d0        xfs_trans_get_efd [xfs]
>               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
>               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]

it all subjective, but this format is a bit weird where "addrs" and
"funcs" is in first row to the left. Just makes everything wider. Why
not something like

addr              func
ffffffff9ec44f20  schedule_timeout_interruptible
ffffffff9ec44f60  schedule_timeout_killable
ffffffffc0953a10  xfs_trans_get_buf_map [xfs]
ffffffffc0957320  xfs_trans_get_dqtrx [xfs]

Not it's singular (addr and func) because it's column names,
basically. Can also do "addr func [module]".

>         pids kprobe_multi(559862)
>
> $ tools/bpf/bpftool/bpftool link show -j
> [{"id":52,"type":"kprobe_multi","prog_id":381,"retprobe":0,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]},{"id":53,"type":"kprobe_multi","prog_id":381,"retprobe":1,"func_cnt":7,"funcs":[{"addr":18446744072078249760,"func":"schedule_timeout_interruptible","module":""},{"addr":18446744072078249824,"func":"schedule_timeout_killable","module":""},{"addr":18446744072078249888,"func":"schedule_timeout_uninterruptible","module":""},{"addr":18446744072078249952,"func":"schedule_timeout_idle","module":""},{"addr":18446744072645535952,"func":"xfs_trans_get_efd","module":"[xfs]"},{"addr":18446744072645589520,"func":"xfs_trans_get_buf_map","module":"[xfs]"},{"addr":18446744072645604128,"func":"xfs_trans_get_dqtrx","module":"[xfs]"}],"pids":[{"pid":559862,"comm":"kprobe_multi"}]}]
>
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> ---
>  tools/bpf/bpftool/link.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 108 insertions(+), 1 deletion(-)
>

[...]
Yafang Shao June 17, 2023, 3:08 a.m. UTC | #7
On Sat, Jun 17, 2023 at 1:30 AM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > Show the already expose kprobe_multi link info in bpftool. The result as
> > follows,
> >
> > 52: kprobe_multi  prog 381
> >         retprobe 0  func_cnt 7
> >         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> >               ffffffff9ec44f60        schedule_timeout_killable
> >               ffffffff9ec44fa0        schedule_timeout_uninterruptible
> >               ffffffff9ec44fe0        schedule_timeout_idle
> >               ffffffffc09468d0        xfs_trans_get_efd [xfs]
> >               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> >               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
> >         pids kprobe_multi(559862)
> > 53: kprobe_multi  prog 381
> >         retprobe 1  func_cnt 7
> >         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> >               ffffffff9ec44f60        schedule_timeout_killable
> >               ffffffff9ec44fa0        schedule_timeout_uninterruptible
> >               ffffffff9ec44fe0        schedule_timeout_idle
> >               ffffffffc09468d0        xfs_trans_get_efd [xfs]
> >               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> >               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
>
> it all subjective, but this format is a bit weird where "addrs" and
> "funcs" is in first row to the left. Just makes everything wider. Why
> not something like
>
> addr              func
> ffffffff9ec44f20  schedule_timeout_interruptible
> ffffffff9ec44f60  schedule_timeout_killable
> ffffffffc0953a10  xfs_trans_get_buf_map [xfs]
> ffffffffc0957320  xfs_trans_get_dqtrx [xfs]

It may be a little strange if there's only one function, but I don't
mind doing it as you suggested.

>
> Not it's singular (addr and func) because it's column names,
> basically. Can also do "addr func [module]".

The length of the function name is variable, so it is not easy to
determine where to put the "[module]". So I prefer to not show  the
"[module]".
Andrii Nakryiko June 20, 2023, 5:17 p.m. UTC | #8
On Fri, Jun 16, 2023 at 8:09 PM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> On Sat, Jun 17, 2023 at 1:30 AM Andrii Nakryiko
> <andrii.nakryiko@gmail.com> wrote:
> >
> > On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > >
> > > Show the already expose kprobe_multi link info in bpftool. The result as
> > > follows,
> > >
> > > 52: kprobe_multi  prog 381
> > >         retprobe 0  func_cnt 7
> > >         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> > >               ffffffff9ec44f60        schedule_timeout_killable
> > >               ffffffff9ec44fa0        schedule_timeout_uninterruptible
> > >               ffffffff9ec44fe0        schedule_timeout_idle
> > >               ffffffffc09468d0        xfs_trans_get_efd [xfs]
> > >               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> > >               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
> > >         pids kprobe_multi(559862)
> > > 53: kprobe_multi  prog 381
> > >         retprobe 1  func_cnt 7
> > >         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> > >               ffffffff9ec44f60        schedule_timeout_killable
> > >               ffffffff9ec44fa0        schedule_timeout_uninterruptible
> > >               ffffffff9ec44fe0        schedule_timeout_idle
> > >               ffffffffc09468d0        xfs_trans_get_efd [xfs]
> > >               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> > >               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
> >
> > it all subjective, but this format is a bit weird where "addrs" and
> > "funcs" is in first row to the left. Just makes everything wider. Why
> > not something like
> >
> > addr              func
> > ffffffff9ec44f20  schedule_timeout_interruptible
> > ffffffff9ec44f60  schedule_timeout_killable
> > ffffffffc0953a10  xfs_trans_get_buf_map [xfs]
> > ffffffffc0957320  xfs_trans_get_dqtrx [xfs]
>
> It may be a little strange if there's only one function, but I don't
> mind doing it as you suggested.
>
> >
> > Not it's singular (addr and func) because it's column names,
> > basically. Can also do "addr func [module]".
>
> The length of the function name is variable, so it is not easy to
> determine where to put the "[module]". So I prefer to not show  the
> "[module]".

"func [module]" in the header will give a hint of what is that value
in square brackets. I didn't mean to align it into a third column


>
> --
> Regards
> Yafang
Yafang Shao June 21, 2023, 1:29 a.m. UTC | #9
On Wed, Jun 21, 2023 at 1:17 AM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Fri, Jun 16, 2023 at 8:09 PM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > On Sat, Jun 17, 2023 at 1:30 AM Andrii Nakryiko
> > <andrii.nakryiko@gmail.com> wrote:
> > >
> > > On Mon, Jun 12, 2023 at 8:16 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > > >
> > > > Show the already expose kprobe_multi link info in bpftool. The result as
> > > > follows,
> > > >
> > > > 52: kprobe_multi  prog 381
> > > >         retprobe 0  func_cnt 7
> > > >         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> > > >               ffffffff9ec44f60        schedule_timeout_killable
> > > >               ffffffff9ec44fa0        schedule_timeout_uninterruptible
> > > >               ffffffff9ec44fe0        schedule_timeout_idle
> > > >               ffffffffc09468d0        xfs_trans_get_efd [xfs]
> > > >               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> > > >               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
> > > >         pids kprobe_multi(559862)
> > > > 53: kprobe_multi  prog 381
> > > >         retprobe 1  func_cnt 7
> > > >         addrs ffffffff9ec44f20  funcs schedule_timeout_interruptible
> > > >               ffffffff9ec44f60        schedule_timeout_killable
> > > >               ffffffff9ec44fa0        schedule_timeout_uninterruptible
> > > >               ffffffff9ec44fe0        schedule_timeout_idle
> > > >               ffffffffc09468d0        xfs_trans_get_efd [xfs]
> > > >               ffffffffc0953a10        xfs_trans_get_buf_map [xfs]
> > > >               ffffffffc0957320        xfs_trans_get_dqtrx [xfs]
> > >
> > > it all subjective, but this format is a bit weird where "addrs" and
> > > "funcs" is in first row to the left. Just makes everything wider. Why
> > > not something like
> > >
> > > addr              func
> > > ffffffff9ec44f20  schedule_timeout_interruptible
> > > ffffffff9ec44f60  schedule_timeout_killable
> > > ffffffffc0953a10  xfs_trans_get_buf_map [xfs]
> > > ffffffffc0957320  xfs_trans_get_dqtrx [xfs]
> >
> > It may be a little strange if there's only one function, but I don't
> > mind doing it as you suggested.
> >
> > >
> > > Not it's singular (addr and func) because it's column names,
> > > basically. Can also do "addr func [module]".
> >
> > The length of the function name is variable, so it is not easy to
> > determine where to put the "[module]". So I prefer to not show  the
> > "[module]".
>
> "func [module]" in the header will give a hint of what is that value
> in square brackets. I didn't mean to align it into a third column

Thanks for the clarification. Will change it.
diff mbox series

Patch

diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
index 2d78607..0015582 100644
--- a/tools/bpf/bpftool/link.c
+++ b/tools/bpf/bpftool/link.c
@@ -14,8 +14,10 @@ 
 
 #include "json_writer.h"
 #include "main.h"
+#include "xlated_dumper.h"
 
 static struct hashmap *link_table;
+static struct dump_data dd = {};
 
 static int link_parse_fd(int *argc, char ***argv)
 {
@@ -166,6 +168,45 @@  static int get_prog_info(int prog_id, struct bpf_prog_info *info)
 	return err;
 }
 
+static int cmp_u64(const void *A, const void *B)
+{
+	const __u64 *a = A, *b = B;
+
+	return *a - *b;
+}
+
+static void
+show_kprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
+{
+	__u32 i, j = 0;
+	__u64 *addrs;
+
+	jsonw_uint_field(json_wtr, "retprobe",
+			 info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN);
+	jsonw_uint_field(json_wtr, "func_cnt", info->kprobe_multi.count);
+	jsonw_name(json_wtr, "funcs");
+	jsonw_start_array(json_wtr);
+	addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
+	qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
+
+	/* Load it once for all. */
+	if (!dd.sym_count)
+		kernel_syms_load(&dd);
+	for (i = 0; i < dd.sym_count; i++) {
+		if (dd.sym_mapping[i].address != addrs[j])
+			continue;
+		jsonw_start_object(json_wtr);
+		jsonw_uint_field(json_wtr, "addr", dd.sym_mapping[i].address);
+		jsonw_string_field(json_wtr, "func", dd.sym_mapping[i].name);
+		/* Print none if it is vmlinux */
+		jsonw_string_field(json_wtr, "module", dd.sym_mapping[i].module);
+		jsonw_end_object(json_wtr);
+		if (j++ == info->kprobe_multi.count)
+			break;
+	}
+	jsonw_end_array(json_wtr);
+}
+
 static int show_link_close_json(int fd, struct bpf_link_info *info)
 {
 	struct bpf_prog_info prog_info;
@@ -218,6 +259,9 @@  static int show_link_close_json(int fd, struct bpf_link_info *info)
 		jsonw_uint_field(json_wtr, "map_id",
 				 info->struct_ops.map_id);
 		break;
+	case BPF_LINK_TYPE_KPROBE_MULTI:
+		show_kprobe_multi_json(info, json_wtr);
+		break;
 	default:
 		break;
 	}
@@ -351,6 +395,44 @@  void netfilter_dump_plain(const struct bpf_link_info *info)
 		printf(" flags 0x%x", info->netfilter.flags);
 }
 
+static void show_kprobe_multi_plain(struct bpf_link_info *info)
+{
+	__u32 i, j = 0;
+	__u64 *addrs;
+
+	if (!info->kprobe_multi.count)
+		return;
+
+	printf("\n\tretprobe %d  func_cnt %u  ",
+	       info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN,
+	       info->kprobe_multi.count);
+	addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
+	qsort((void *)addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
+
+	/* Load it once for all. */
+	if (!dd.sym_count)
+		kernel_syms_load(&dd);
+	for (i = 0; i < dd.sym_count; i++) {
+		if (dd.sym_mapping[i].address != addrs[j])
+			continue;
+		if (!j)
+			printf("\n\taddrs %016lx  funcs %s",
+			       dd.sym_mapping[i].address,
+			       dd.sym_mapping[i].name);
+		else
+			printf("\n\t      %016lx        %s",
+			       dd.sym_mapping[i].address,
+			       dd.sym_mapping[i].name);
+		if (dd.sym_mapping[i].module[0] != '\0')
+			printf(" %s  ", dd.sym_mapping[i].module);
+		else
+			printf("  ");
+
+		if (j++ == info->kprobe_multi.count)
+			break;
+	}
+}
+
 static int show_link_close_plain(int fd, struct bpf_link_info *info)
 {
 	struct bpf_prog_info prog_info;
@@ -396,6 +478,9 @@  static int show_link_close_plain(int fd, struct bpf_link_info *info)
 	case BPF_LINK_TYPE_NETFILTER:
 		netfilter_dump_plain(info);
 		break;
+	case BPF_LINK_TYPE_KPROBE_MULTI:
+		show_kprobe_multi_plain(info);
+		break;
 	default:
 		break;
 	}
@@ -417,7 +502,9 @@  static int do_show_link(int fd)
 {
 	struct bpf_link_info info;
 	__u32 len = sizeof(info);
+	__u64 *addrs = NULL;
 	char buf[256];
+	int count;
 	int err;
 
 	memset(&info, 0, sizeof(info));
@@ -441,12 +528,28 @@  static int do_show_link(int fd)
 		info.iter.target_name_len = sizeof(buf);
 		goto again;
 	}
+	if (info.type == BPF_LINK_TYPE_KPROBE_MULTI &&
+	    !info.kprobe_multi.addrs) {
+		count = info.kprobe_multi.count;
+		if (count) {
+			addrs = calloc(count, sizeof(__u64));
+			if (!addrs) {
+				p_err("mem alloc failed");
+				close(fd);
+				return -1;
+			}
+			info.kprobe_multi.addrs = (unsigned long)addrs;
+			goto again;
+		}
+	}
 
 	if (json_output)
 		show_link_close_json(fd, &info);
 	else
 		show_link_close_plain(fd, &info);
 
+	if (addrs)
+		free(addrs);
 	close(fd);
 	return 0;
 }
@@ -471,7 +574,8 @@  static int do_show(int argc, char **argv)
 		fd = link_parse_fd(&argc, &argv);
 		if (fd < 0)
 			return fd;
-		return do_show_link(fd);
+		do_show_link(fd);
+		goto out;
 	}
 
 	if (argc)
@@ -510,6 +614,9 @@  static int do_show(int argc, char **argv)
 	if (show_pinned)
 		delete_pinned_obj_table(link_table);
 
+out:
+	if (dd.sym_count)
+		kernel_syms_destroy(&dd);
 	return errno == ENOENT ? 0 : -1;
 }