diff mbox series

[v2,bpf-next,09/11] libbpf: Add perf event names

Message ID 20230608103523.102267-10-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
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-6 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for test_maps on aarch64 with gcc
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-25 success Logs for test_verifier on aarch64 with gcc
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 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success 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 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
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-23 success Logs for test_progs_parallel on x86_64 with gcc
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-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-26 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_progs on s390x with gcc
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 12 of 12 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 success total: 0 errors, 0 warnings, 0 checks, 197 lines checked
netdev/kdoc fail Errors and warnings before: 116 this patch: 128
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-8 success Logs for test_maps on s390x with gcc

Commit Message

Yafang Shao June 8, 2023, 10:35 a.m. UTC
Add libbpf API to get generic perf event name.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 tools/lib/bpf/libbpf.c   | 107 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h   |  56 +++++++++++++++++++++++++
 tools/lib/bpf/libbpf.map |   6 +++
 3 files changed, 169 insertions(+)

Comments

Andrii Nakryiko June 8, 2023, 11:14 p.m. UTC | #1
On Thu, Jun 8, 2023 at 3:35 AM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> Add libbpf API to get generic perf event name.
>
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> ---

I don't think this belongs in libbpf and shouldn't be exposed as
public API. Please move it into bpftool and make it internal (if
Quentin is fine with this in the first place).


>  tools/lib/bpf/libbpf.c   | 107 +++++++++++++++++++++++++++++++++++++++++++++++
>  tools/lib/bpf/libbpf.h   |  56 +++++++++++++++++++++++++
>  tools/lib/bpf/libbpf.map |   6 +++
>  3 files changed, 169 insertions(+)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 47632606..27d396f 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -119,6 +119,64 @@
>         [BPF_STRUCT_OPS]                = "struct_ops",
>  };
>
> +static const char * const perf_type_name[] = {
> +       [PERF_TYPE_HARDWARE]            = "hardware",
> +       [PERF_TYPE_SOFTWARE]            = "software",
> +       [PERF_TYPE_TRACEPOINT]          = "tracepoint",
> +       [PERF_TYPE_HW_CACHE]            = "hw_cache",
> +       [PERF_TYPE_RAW]                 = "raw",
> +       [PERF_TYPE_BREAKPOINT]          = "breakpoint",
> +};
> +
> +static const char * const perf_hw_name[] = {
> +       [PERF_COUNT_HW_CPU_CYCLES]              = "cpu_cycles",
> +       [PERF_COUNT_HW_INSTRUCTIONS]            = "instructions",
> +       [PERF_COUNT_HW_CACHE_REFERENCES]        = "cache_references",
> +       [PERF_COUNT_HW_CACHE_MISSES]            = "cache_misses",
> +       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = "branch_instructions",
> +       [PERF_COUNT_HW_BRANCH_MISSES]           = "branch_misses",
> +       [PERF_COUNT_HW_BUS_CYCLES]              = "bus_cycles",
> +       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "stalled_cycles_frontend",
> +       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = "stalled_cycles_backend",
> +       [PERF_COUNT_HW_REF_CPU_CYCLES]          = "ref_cpu_cycles",
> +};
> +
> +static const char * const perf_hw_cache_name[] = {
> +       [PERF_COUNT_HW_CACHE_L1D]               = "l1d",
> +       [PERF_COUNT_HW_CACHE_L1I]               = "l1i",
> +       [PERF_COUNT_HW_CACHE_LL]                = "ll",
> +       [PERF_COUNT_HW_CACHE_DTLB]              = "dtlb",
> +       [PERF_COUNT_HW_CACHE_ITLB]              = "itlb",
> +       [PERF_COUNT_HW_CACHE_BPU]               = "bpu",
> +       [PERF_COUNT_HW_CACHE_NODE]              = "node",
> +};
> +
> +static const char * const perf_hw_cache_op_name[] = {
> +       [PERF_COUNT_HW_CACHE_OP_READ]           = "read",
> +       [PERF_COUNT_HW_CACHE_OP_WRITE]          = "write",
> +       [PERF_COUNT_HW_CACHE_OP_PREFETCH]       = "prefetch",
> +};
> +
> +static const char * const perf_hw_cache_op_result_name[] = {
> +       [PERF_COUNT_HW_CACHE_RESULT_ACCESS]     = "access",
> +       [PERF_COUNT_HW_CACHE_RESULT_MISS]       = "miss",
> +};
> +
> +static const char * const perf_sw_name[] = {
> +       [PERF_COUNT_SW_CPU_CLOCK]               = "cpu_clock",
> +       [PERF_COUNT_SW_TASK_CLOCK]              = "task_clock",
> +       [PERF_COUNT_SW_PAGE_FAULTS]             = "page_faults",
> +       [PERF_COUNT_SW_CONTEXT_SWITCHES]        = "context_switches",
> +       [PERF_COUNT_SW_CPU_MIGRATIONS]          = "cpu_migrations",
> +       [PERF_COUNT_SW_PAGE_FAULTS_MIN]         = "page_faults_min",
> +       [PERF_COUNT_SW_PAGE_FAULTS_MAJ]         = "page_faults_maj",
> +       [PERF_COUNT_SW_ALIGNMENT_FAULTS]        = "alignment_faults",
> +       [PERF_COUNT_SW_EMULATION_FAULTS]        = "emulation_faults",
> +       [PERF_COUNT_SW_DUMMY]                   = "dummy",
> +       [PERF_COUNT_SW_BPF_OUTPUT]              = "bpf_output",
> +       [PERF_COUNT_SW_CGROUP_SWITCHES]         = "cgroup_switches",
> +};
> +
>  static const char * const link_type_name[] = {
>         [BPF_LINK_TYPE_UNSPEC]                  = "unspec",
>         [BPF_LINK_TYPE_RAW_TRACEPOINT]          = "raw_tracepoint",
> @@ -8953,6 +9011,55 @@ const char *libbpf_bpf_attach_type_str(enum bpf_attach_type t)
>         return attach_type_name[t];
>  }
>
> +const char *libbpf_perf_type_str(enum perf_type_id t)
> +{
> +       if (t < 0 || t >= ARRAY_SIZE(perf_type_name))
> +               return NULL;
> +
> +       return perf_type_name[t];
> +}
> +
> +const char *libbpf_perf_hw_str(enum perf_hw_id t)
> +{
> +       if (t < 0 || t >= ARRAY_SIZE(perf_hw_name))
> +               return NULL;
> +
> +       return perf_hw_name[t];
> +}
> +
> +const char *libbpf_perf_hw_cache_str(enum perf_hw_cache_id t)
> +{
> +       if (t < 0 || t >= ARRAY_SIZE(perf_hw_cache_name))
> +               return NULL;
> +
> +       return perf_hw_cache_name[t];
> +}
> +
> +const char *libbpf_perf_hw_cache_op_str(enum perf_hw_cache_op_id t)
> +{
> +       if (t < 0 || t >= ARRAY_SIZE(perf_hw_cache_op_name))
> +               return NULL;
> +
> +       return perf_hw_cache_op_name[t];
> +}
> +
> +const char *
> +libbpf_perf_hw_cache_op_result_str(enum perf_hw_cache_op_result_id t)
> +{
> +       if (t < 0 || t >= ARRAY_SIZE(perf_hw_cache_op_result_name))
> +               return NULL;
> +
> +       return perf_hw_cache_op_result_name[t];
> +}
> +
> +const char *libbpf_perf_sw_str(enum perf_sw_ids t)
> +{
> +       if (t < 0 || t >= ARRAY_SIZE(perf_sw_name))
> +               return NULL;
> +
> +       return perf_sw_name[t];
> +}
> +
>  const char *libbpf_bpf_link_type_str(enum bpf_link_type t)
>  {
>         if (t < 0 || t >= ARRAY_SIZE(link_type_name))
> diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
> index 754da73..4123e4c 100644
> --- a/tools/lib/bpf/libbpf.h
> +++ b/tools/lib/bpf/libbpf.h
> @@ -16,6 +16,7 @@
>  #include <stdbool.h>
>  #include <sys/types.h>  // for size_t
>  #include <linux/bpf.h>
> +#include <linux/perf_event.h>
>
>  #include "libbpf_common.h"
>  #include "libbpf_legacy.h"
> @@ -61,6 +62,61 @@ enum libbpf_errno {
>  LIBBPF_API const char *libbpf_bpf_attach_type_str(enum bpf_attach_type t);
>
>  /**
> + * @brief **libbpf_perf_type_str()** converts the provided perf type value
> + * into a textual representation.
> + * @param t The perf type.
> + * @return Pointer to a static string identifying the perf type. NULL is
> + * returned for unknown **perf_type_id** values.
> + */
> +LIBBPF_API const char *libbpf_perf_type_str(enum perf_type_id t);
> +
> +/**
> + * @brief **libbpf_perf_hw_str()** converts the provided perf hw id
> + * into a textual representation.
> + * @param t The perf hw id.
> + * @return Pointer to a static string identifying the perf hw id. NULL is
> + * returned for unknown **perf_hw_id** values.
> + */
> +LIBBPF_API const char *libbpf_perf_hw_str(enum perf_hw_id t);
> +
> +/**
> + * @brief **libbpf_perf_hw_cache_str()** converts the provided perf hw cache
> + * id into a textual representation.
> + * @param t The perf hw cache id.
> + * @return Pointer to a static string identifying the perf hw cache id.
> + * NULL is returned for unknown **perf_hw_cache_id** values.
> + */
> +LIBBPF_API const char *libbpf_perf_hw_cache_str(enum perf_hw_cache_id t);
> +
> +/**
> + * @brief **libbpf_perf_hw_cache_op_str()** converts the provided perf hw
> + * cache op id into a textual representation.
> + * @param t The perf hw cache op id.
> + * @return Pointer to a static string identifying the perf hw cache op id.
> + * NULL is returned for unknown **perf_hw_cache_op_id** values.
> + */
> +LIBBPF_API const char *libbpf_perf_hw_cache_op_str(enum perf_hw_cache_op_id t);
> +
> +/**
> + * @brief **libbpf_perf_hw_cache_op_result_str()** converts the provided
> + * perf hw cache op result id into a textual representation.
> + * @param t The perf hw cache op result id.
> + * @return Pointer to a static string identifying the perf hw cache op result
> + * id. NULL is returned for unknown **perf_hw_cache_op_result_id** values.
> + */
> +LIBBPF_API const char *
> +libbpf_perf_hw_cache_op_result_str(enum perf_hw_cache_op_result_id t);
> +
> +/**
> + * @brief **libbpf_perf_sw_str()** converts the provided perf sw id
> + * into a textual representation.
> + * @param t The perf sw id.
> + * @return Pointer to a static string identifying the perf sw id. NULL is
> + * returned for unknown **perf_sw_ids** values.
> + */
> +LIBBPF_API const char *libbpf_perf_sw_str(enum perf_sw_ids t);
> +
> +/**
>   * @brief **libbpf_bpf_link_type_str()** converts the provided link type value
>   * into a textual representation.
>   * @param t The link type.
> diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
> index 7521a2f..6ae0a36 100644
> --- a/tools/lib/bpf/libbpf.map
> +++ b/tools/lib/bpf/libbpf.map
> @@ -395,4 +395,10 @@ LIBBPF_1.2.0 {
>  LIBBPF_1.3.0 {
>         global:
>                 bpf_obj_pin_opts;
> +               libbpf_perf_hw_cache_op_result_str;
> +               libbpf_perf_hw_cache_op_str;
> +               libbpf_perf_hw_cache_str;
> +               libbpf_perf_hw_str;
> +               libbpf_perf_sw_str;
> +               libbpf_perf_type_str;
>  } LIBBPF_1.2.0;
> --
> 1.8.3.1
>
Song Liu June 9, 2023, 4:36 a.m. UTC | #2
On Thu, Jun 8, 2023 at 4:14 PM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Thu, Jun 8, 2023 at 3:35 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > Add libbpf API to get generic perf event name.
> >
> > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > ---
>
> I don't think this belongs in libbpf and shouldn't be exposed as
> public API. Please move it into bpftool and make it internal (if
> Quentin is fine with this in the first place).

Or maybe it belongs to libperf?

Thanks,
Song
Yafang Shao June 10, 2023, 2:22 a.m. UTC | #3
On Fri, Jun 9, 2023 at 12:36 PM Song Liu <song@kernel.org> wrote:
>
> On Thu, Jun 8, 2023 at 4:14 PM Andrii Nakryiko
> <andrii.nakryiko@gmail.com> wrote:
> >
> > On Thu, Jun 8, 2023 at 3:35 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > >
> > > Add libbpf API to get generic perf event name.
> > >
> > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > ---
> >
> > I don't think this belongs in libbpf and shouldn't be exposed as
> > public API. Please move it into bpftool and make it internal (if
> > Quentin is fine with this in the first place).
>
> Or maybe it belongs to libperf?

I prefer to move it into libperf.  Then it may be reused by other tools.
Quentin Monnet June 10, 2023, 8:34 p.m. UTC | #4
On Sat, 10 Jun 2023 at 03:22, Yafang Shao <laoar.shao@gmail.com> wrote:
>
> On Fri, Jun 9, 2023 at 12:36 PM Song Liu <song@kernel.org> wrote:
> >
> > On Thu, Jun 8, 2023 at 4:14 PM Andrii Nakryiko
> > <andrii.nakryiko@gmail.com> wrote:
> > >
> > > On Thu, Jun 8, 2023 at 3:35 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > > >
> > > > Add libbpf API to get generic perf event name.
> > > >
> > > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > > ---
> > >
> > > I don't think this belongs in libbpf and shouldn't be exposed as
> > > public API. Please move it into bpftool and make it internal (if
> > > Quentin is fine with this in the first place).

Fine by me

> >
> > Or maybe it belongs to libperf?
>
> I prefer to move it into libperf.  Then it may be reused by other tools.

Libperf sounds like a good place to have it, and I'm all in favour of
having the names available to other tools, too.

This being said, this would add a new dependency to bpftool. I'm not
sure it's worth building libperf from bpftool's Makefile like we do
for libbpf, just for getting the names: it would add to build time,
and I don't see an easy way to replicate it on the GitHub mirror
anyway. So the remaining option would be to use the library installed
on the system if available, and to have a new feature detection in
bpftool to figure out if the functions are available; but this also
means most users compiling locally wouldn't get the names by default.

Looking at the list in the UAPI header, it seems to be relatively
stable, so I'm fine with having it in bpftool, it shouldn't be too
much overhead to keep up-to-date.

Too bad these are enums and not macros in the UAPI, or we'd be able to
derive the name without these arrays, given that it's just trimming
the prefix and turning to lowercase. But maybe an alternative solution
would be to get the name of the enum members with BTF, and derive the
names from there? We already (optionally) rely on vmlinux.h at build
time, maybe we can just reuse it?

Quentin
Jiri Olsa June 10, 2023, 10:37 p.m. UTC | #5
On Thu, Jun 08, 2023 at 09:36:39PM -0700, Song Liu wrote:
> On Thu, Jun 8, 2023 at 4:14 PM Andrii Nakryiko
> <andrii.nakryiko@gmail.com> wrote:
> >
> > On Thu, Jun 8, 2023 at 3:35 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > >
> > > Add libbpf API to get generic perf event name.
> > >
> > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > ---
> >
> > I don't think this belongs in libbpf and shouldn't be exposed as
> > public API. Please move it into bpftool and make it internal (if
> > Quentin is fine with this in the first place).
> 
> Or maybe it belongs to libperf?

we have several lookup arrays like that in perf and we keep
also 'alias' names.. it'd be good idea to have that only in
libperf, but that would require perf perf's parse-events
cleanup as well and bpftool starting to link libperf

I'd keep it in bpftool for now and have that cleanup later

cc-ing Arnaldo

jirka

> 
> Thanks,
> Song
Jiri Olsa June 10, 2023, 10:43 p.m. UTC | #6
On Thu, Jun 08, 2023 at 10:35:21AM +0000, Yafang Shao wrote:
> Add libbpf API to get generic perf event name.
> 
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> ---
>  tools/lib/bpf/libbpf.c   | 107 +++++++++++++++++++++++++++++++++++++++++++++++
>  tools/lib/bpf/libbpf.h   |  56 +++++++++++++++++++++++++
>  tools/lib/bpf/libbpf.map |   6 +++
>  3 files changed, 169 insertions(+)
> 
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 47632606..27d396f 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -119,6 +119,64 @@
>  	[BPF_STRUCT_OPS]		= "struct_ops",
>  };
>  
> +static const char * const perf_type_name[] = {
> +	[PERF_TYPE_HARDWARE]		= "hardware",
> +	[PERF_TYPE_SOFTWARE]		= "software",
> +	[PERF_TYPE_TRACEPOINT]		= "tracepoint",
> +	[PERF_TYPE_HW_CACHE]		= "hw_cache",
> +	[PERF_TYPE_RAW]			= "raw",
> +	[PERF_TYPE_BREAKPOINT]		= "breakpoint",
> +};
> +
> +static const char * const perf_hw_name[] = {
> +	[PERF_COUNT_HW_CPU_CYCLES]		= "cpu_cycles",

could you use '-' instead of '_' because that's what we do in perf

actually would be great if you could use same names like in
  tool/perf/util/parse-events.c  'event_symbols_*' arrays
  tool/perf/util/evsel.c         'evsel__hw_cache' array

so perf and bpftool would use same names and we have a chance
to use same code for that in future

jirka

> +	[PERF_COUNT_HW_INSTRUCTIONS]		= "instructions",
> +	[PERF_COUNT_HW_CACHE_REFERENCES]	= "cache_references",
> +	[PERF_COUNT_HW_CACHE_MISSES]		= "cache_misses",
> +	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= "branch_instructions",
> +	[PERF_COUNT_HW_BRANCH_MISSES]		= "branch_misses",
> +	[PERF_COUNT_HW_BUS_CYCLES]		= "bus_cycles",
> +	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= "stalled_cycles_frontend",
> +	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= "stalled_cycles_backend",
> +	[PERF_COUNT_HW_REF_CPU_CYCLES]		= "ref_cpu_cycles",
> +};
> +
> +static const char * const perf_hw_cache_name[] = {
> +	[PERF_COUNT_HW_CACHE_L1D]		= "l1d",
> +	[PERF_COUNT_HW_CACHE_L1I]		= "l1i",
> +	[PERF_COUNT_HW_CACHE_LL]		= "ll",
> +	[PERF_COUNT_HW_CACHE_DTLB]		= "dtlb",
> +	[PERF_COUNT_HW_CACHE_ITLB]		= "itlb",
> +	[PERF_COUNT_HW_CACHE_BPU]		= "bpu",
> +	[PERF_COUNT_HW_CACHE_NODE]		= "node",
> +};
> +
> +static const char * const perf_hw_cache_op_name[] = {
> +	[PERF_COUNT_HW_CACHE_OP_READ]		= "read",
> +	[PERF_COUNT_HW_CACHE_OP_WRITE]		= "write",
> +	[PERF_COUNT_HW_CACHE_OP_PREFETCH]	= "prefetch",
> +};
> +
> +static const char * const perf_hw_cache_op_result_name[] = {
> +	[PERF_COUNT_HW_CACHE_RESULT_ACCESS]	= "access",
> +	[PERF_COUNT_HW_CACHE_RESULT_MISS]	= "miss",
> +};
> +
> +static const char * const perf_sw_name[] = {
> +	[PERF_COUNT_SW_CPU_CLOCK]		= "cpu_clock",
> +	[PERF_COUNT_SW_TASK_CLOCK]		= "task_clock",
> +	[PERF_COUNT_SW_PAGE_FAULTS]		= "page_faults",
> +	[PERF_COUNT_SW_CONTEXT_SWITCHES]	= "context_switches",
> +	[PERF_COUNT_SW_CPU_MIGRATIONS]		= "cpu_migrations",
> +	[PERF_COUNT_SW_PAGE_FAULTS_MIN]		= "page_faults_min",
> +	[PERF_COUNT_SW_PAGE_FAULTS_MAJ]		= "page_faults_maj",
> +	[PERF_COUNT_SW_ALIGNMENT_FAULTS]	= "alignment_faults",
> +	[PERF_COUNT_SW_EMULATION_FAULTS]	= "emulation_faults",
> +	[PERF_COUNT_SW_DUMMY]			= "dummy",
> +	[PERF_COUNT_SW_BPF_OUTPUT]		= "bpf_output",
> +	[PERF_COUNT_SW_CGROUP_SWITCHES]		= "cgroup_switches",
> +};
> +
>  static const char * const link_type_name[] = {
>  	[BPF_LINK_TYPE_UNSPEC]			= "unspec",
>  	[BPF_LINK_TYPE_RAW_TRACEPOINT]		= "raw_tracepoint",
> @@ -8953,6 +9011,55 @@ const char *libbpf_bpf_attach_type_str(enum bpf_attach_type t)
>  	return attach_type_name[t];
>  }
>  
> +const char *libbpf_perf_type_str(enum perf_type_id t)
> +{
> +	if (t < 0 || t >= ARRAY_SIZE(perf_type_name))
> +		return NULL;
> +
> +	return perf_type_name[t];
> +}
> +
> +const char *libbpf_perf_hw_str(enum perf_hw_id t)
> +{
> +	if (t < 0 || t >= ARRAY_SIZE(perf_hw_name))
> +		return NULL;
> +
> +	return perf_hw_name[t];
> +}
> +
> +const char *libbpf_perf_hw_cache_str(enum perf_hw_cache_id t)
> +{
> +	if (t < 0 || t >= ARRAY_SIZE(perf_hw_cache_name))
> +		return NULL;
> +
> +	return perf_hw_cache_name[t];
> +}
> +
> +const char *libbpf_perf_hw_cache_op_str(enum perf_hw_cache_op_id t)
> +{
> +	if (t < 0 || t >= ARRAY_SIZE(perf_hw_cache_op_name))
> +		return NULL;
> +
> +	return perf_hw_cache_op_name[t];
> +}
> +
> +const char *
> +libbpf_perf_hw_cache_op_result_str(enum perf_hw_cache_op_result_id t)
> +{
> +	if (t < 0 || t >= ARRAY_SIZE(perf_hw_cache_op_result_name))
> +		return NULL;
> +
> +	return perf_hw_cache_op_result_name[t];
> +}
> +
> +const char *libbpf_perf_sw_str(enum perf_sw_ids t)
> +{
> +	if (t < 0 || t >= ARRAY_SIZE(perf_sw_name))
> +		return NULL;
> +
> +	return perf_sw_name[t];
> +}
> +
>  const char *libbpf_bpf_link_type_str(enum bpf_link_type t)
>  {
>  	if (t < 0 || t >= ARRAY_SIZE(link_type_name))
> diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
> index 754da73..4123e4c 100644
> --- a/tools/lib/bpf/libbpf.h
> +++ b/tools/lib/bpf/libbpf.h
> @@ -16,6 +16,7 @@
>  #include <stdbool.h>
>  #include <sys/types.h>  // for size_t
>  #include <linux/bpf.h>
> +#include <linux/perf_event.h>
>  
>  #include "libbpf_common.h"
>  #include "libbpf_legacy.h"
> @@ -61,6 +62,61 @@ enum libbpf_errno {
>  LIBBPF_API const char *libbpf_bpf_attach_type_str(enum bpf_attach_type t);
>  
>  /**
> + * @brief **libbpf_perf_type_str()** converts the provided perf type value
> + * into a textual representation.
> + * @param t The perf type.
> + * @return Pointer to a static string identifying the perf type. NULL is
> + * returned for unknown **perf_type_id** values.
> + */
> +LIBBPF_API const char *libbpf_perf_type_str(enum perf_type_id t);
> +
> +/**
> + * @brief **libbpf_perf_hw_str()** converts the provided perf hw id
> + * into a textual representation.
> + * @param t The perf hw id.
> + * @return Pointer to a static string identifying the perf hw id. NULL is
> + * returned for unknown **perf_hw_id** values.
> + */
> +LIBBPF_API const char *libbpf_perf_hw_str(enum perf_hw_id t);
> +
> +/**
> + * @brief **libbpf_perf_hw_cache_str()** converts the provided perf hw cache
> + * id into a textual representation.
> + * @param t The perf hw cache id.
> + * @return Pointer to a static string identifying the perf hw cache id.
> + * NULL is returned for unknown **perf_hw_cache_id** values.
> + */
> +LIBBPF_API const char *libbpf_perf_hw_cache_str(enum perf_hw_cache_id t);
> +
> +/**
> + * @brief **libbpf_perf_hw_cache_op_str()** converts the provided perf hw
> + * cache op id into a textual representation.
> + * @param t The perf hw cache op id.
> + * @return Pointer to a static string identifying the perf hw cache op id.
> + * NULL is returned for unknown **perf_hw_cache_op_id** values.
> + */
> +LIBBPF_API const char *libbpf_perf_hw_cache_op_str(enum perf_hw_cache_op_id t);
> +
> +/**
> + * @brief **libbpf_perf_hw_cache_op_result_str()** converts the provided
> + * perf hw cache op result id into a textual representation.
> + * @param t The perf hw cache op result id.
> + * @return Pointer to a static string identifying the perf hw cache op result
> + * id. NULL is returned for unknown **perf_hw_cache_op_result_id** values.
> + */
> +LIBBPF_API const char *
> +libbpf_perf_hw_cache_op_result_str(enum perf_hw_cache_op_result_id t);
> +
> +/**
> + * @brief **libbpf_perf_sw_str()** converts the provided perf sw id
> + * into a textual representation.
> + * @param t The perf sw id.
> + * @return Pointer to a static string identifying the perf sw id. NULL is
> + * returned for unknown **perf_sw_ids** values.
> + */
> +LIBBPF_API const char *libbpf_perf_sw_str(enum perf_sw_ids t);
> +
> +/**
>   * @brief **libbpf_bpf_link_type_str()** converts the provided link type value
>   * into a textual representation.
>   * @param t The link type.
> diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
> index 7521a2f..6ae0a36 100644
> --- a/tools/lib/bpf/libbpf.map
> +++ b/tools/lib/bpf/libbpf.map
> @@ -395,4 +395,10 @@ LIBBPF_1.2.0 {
>  LIBBPF_1.3.0 {
>  	global:
>  		bpf_obj_pin_opts;
> +		libbpf_perf_hw_cache_op_result_str;
> +		libbpf_perf_hw_cache_op_str;
> +		libbpf_perf_hw_cache_str;
> +		libbpf_perf_hw_str;
> +		libbpf_perf_sw_str;
> +		libbpf_perf_type_str;
>  } LIBBPF_1.2.0;
> -- 
> 1.8.3.1
>
Yafang Shao June 11, 2023, 3:52 p.m. UTC | #7
On Sun, Jun 11, 2023 at 4:35 AM Quentin Monnet <quentin@isovalent.com> wrote:
>
> On Sat, 10 Jun 2023 at 03:22, Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > On Fri, Jun 9, 2023 at 12:36 PM Song Liu <song@kernel.org> wrote:
> > >
> > > On Thu, Jun 8, 2023 at 4:14 PM Andrii Nakryiko
> > > <andrii.nakryiko@gmail.com> wrote:
> > > >
> > > > On Thu, Jun 8, 2023 at 3:35 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > > > >
> > > > > Add libbpf API to get generic perf event name.
> > > > >
> > > > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > > > ---
> > > >
> > > > I don't think this belongs in libbpf and shouldn't be exposed as
> > > > public API. Please move it into bpftool and make it internal (if
> > > > Quentin is fine with this in the first place).
>
> Fine by me

I will move them into bpftool.

>
> > >
> > > Or maybe it belongs to libperf?
> >
> > I prefer to move it into libperf.  Then it may be reused by other tools.
>
> Libperf sounds like a good place to have it, and I'm all in favour of
> having the names available to other tools, too.
>
> This being said, this would add a new dependency to bpftool. I'm not
> sure it's worth building libperf from bpftool's Makefile like we do
> for libbpf, just for getting the names: it would add to build time,
> and I don't see an easy way to replicate it on the GitHub mirror
> anyway. So the remaining option would be to use the library installed
> on the system if available, and to have a new feature detection in
> bpftool to figure out if the functions are available; but this also
> means most users compiling locally wouldn't get the names by default.

Agree with you that dependency is a problem.

>
> Looking at the list in the UAPI header, it seems to be relatively
> stable, so I'm fine with having it in bpftool, it shouldn't be too
> much overhead to keep up-to-date.
>
> Too bad these are enums and not macros in the UAPI, or we'd be able to
> derive the name without these arrays, given that it's just trimming
> the prefix and turning to lowercase. But maybe an alternative solution
> would be to get the name of the enum members with BTF, and derive the
> names from there? We already (optionally) rely on vmlinux.h at build
> time, maybe we can just reuse it?
>

As Jiri suggested, I think we can just put these code into bpftool,
and then try to improve it in the future.
Yafang Shao June 11, 2023, 3:55 p.m. UTC | #8
On Sun, Jun 11, 2023 at 6:43 AM Jiri Olsa <olsajiri@gmail.com> wrote:
>
> On Thu, Jun 08, 2023 at 10:35:21AM +0000, Yafang Shao wrote:
> > Add libbpf API to get generic perf event name.
> >
> > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > ---
> >  tools/lib/bpf/libbpf.c   | 107 +++++++++++++++++++++++++++++++++++++++++++++++
> >  tools/lib/bpf/libbpf.h   |  56 +++++++++++++++++++++++++
> >  tools/lib/bpf/libbpf.map |   6 +++
> >  3 files changed, 169 insertions(+)
> >
> > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> > index 47632606..27d396f 100644
> > --- a/tools/lib/bpf/libbpf.c
> > +++ b/tools/lib/bpf/libbpf.c
> > @@ -119,6 +119,64 @@
> >       [BPF_STRUCT_OPS]                = "struct_ops",
> >  };
> >
> > +static const char * const perf_type_name[] = {
> > +     [PERF_TYPE_HARDWARE]            = "hardware",
> > +     [PERF_TYPE_SOFTWARE]            = "software",
> > +     [PERF_TYPE_TRACEPOINT]          = "tracepoint",
> > +     [PERF_TYPE_HW_CACHE]            = "hw_cache",
> > +     [PERF_TYPE_RAW]                 = "raw",
> > +     [PERF_TYPE_BREAKPOINT]          = "breakpoint",
> > +};
> > +
> > +static const char * const perf_hw_name[] = {
> > +     [PERF_COUNT_HW_CPU_CYCLES]              = "cpu_cycles",
>
> could you use '-' instead of '_' because that's what we do in perf
>
> actually would be great if you could use same names like in
>   tool/perf/util/parse-events.c  'event_symbols_*' arrays
>   tool/perf/util/evsel.c         'evsel__hw_cache' array
>
> so perf and bpftool would use same names and we have a chance
> to use same code for that in future

Good point. Will copy them :)
diff mbox series

Patch

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 47632606..27d396f 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -119,6 +119,64 @@ 
 	[BPF_STRUCT_OPS]		= "struct_ops",
 };
 
+static const char * const perf_type_name[] = {
+	[PERF_TYPE_HARDWARE]		= "hardware",
+	[PERF_TYPE_SOFTWARE]		= "software",
+	[PERF_TYPE_TRACEPOINT]		= "tracepoint",
+	[PERF_TYPE_HW_CACHE]		= "hw_cache",
+	[PERF_TYPE_RAW]			= "raw",
+	[PERF_TYPE_BREAKPOINT]		= "breakpoint",
+};
+
+static const char * const perf_hw_name[] = {
+	[PERF_COUNT_HW_CPU_CYCLES]		= "cpu_cycles",
+	[PERF_COUNT_HW_INSTRUCTIONS]		= "instructions",
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= "cache_references",
+	[PERF_COUNT_HW_CACHE_MISSES]		= "cache_misses",
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= "branch_instructions",
+	[PERF_COUNT_HW_BRANCH_MISSES]		= "branch_misses",
+	[PERF_COUNT_HW_BUS_CYCLES]		= "bus_cycles",
+	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= "stalled_cycles_frontend",
+	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= "stalled_cycles_backend",
+	[PERF_COUNT_HW_REF_CPU_CYCLES]		= "ref_cpu_cycles",
+};
+
+static const char * const perf_hw_cache_name[] = {
+	[PERF_COUNT_HW_CACHE_L1D]		= "l1d",
+	[PERF_COUNT_HW_CACHE_L1I]		= "l1i",
+	[PERF_COUNT_HW_CACHE_LL]		= "ll",
+	[PERF_COUNT_HW_CACHE_DTLB]		= "dtlb",
+	[PERF_COUNT_HW_CACHE_ITLB]		= "itlb",
+	[PERF_COUNT_HW_CACHE_BPU]		= "bpu",
+	[PERF_COUNT_HW_CACHE_NODE]		= "node",
+};
+
+static const char * const perf_hw_cache_op_name[] = {
+	[PERF_COUNT_HW_CACHE_OP_READ]		= "read",
+	[PERF_COUNT_HW_CACHE_OP_WRITE]		= "write",
+	[PERF_COUNT_HW_CACHE_OP_PREFETCH]	= "prefetch",
+};
+
+static const char * const perf_hw_cache_op_result_name[] = {
+	[PERF_COUNT_HW_CACHE_RESULT_ACCESS]	= "access",
+	[PERF_COUNT_HW_CACHE_RESULT_MISS]	= "miss",
+};
+
+static const char * const perf_sw_name[] = {
+	[PERF_COUNT_SW_CPU_CLOCK]		= "cpu_clock",
+	[PERF_COUNT_SW_TASK_CLOCK]		= "task_clock",
+	[PERF_COUNT_SW_PAGE_FAULTS]		= "page_faults",
+	[PERF_COUNT_SW_CONTEXT_SWITCHES]	= "context_switches",
+	[PERF_COUNT_SW_CPU_MIGRATIONS]		= "cpu_migrations",
+	[PERF_COUNT_SW_PAGE_FAULTS_MIN]		= "page_faults_min",
+	[PERF_COUNT_SW_PAGE_FAULTS_MAJ]		= "page_faults_maj",
+	[PERF_COUNT_SW_ALIGNMENT_FAULTS]	= "alignment_faults",
+	[PERF_COUNT_SW_EMULATION_FAULTS]	= "emulation_faults",
+	[PERF_COUNT_SW_DUMMY]			= "dummy",
+	[PERF_COUNT_SW_BPF_OUTPUT]		= "bpf_output",
+	[PERF_COUNT_SW_CGROUP_SWITCHES]		= "cgroup_switches",
+};
+
 static const char * const link_type_name[] = {
 	[BPF_LINK_TYPE_UNSPEC]			= "unspec",
 	[BPF_LINK_TYPE_RAW_TRACEPOINT]		= "raw_tracepoint",
@@ -8953,6 +9011,55 @@  const char *libbpf_bpf_attach_type_str(enum bpf_attach_type t)
 	return attach_type_name[t];
 }
 
+const char *libbpf_perf_type_str(enum perf_type_id t)
+{
+	if (t < 0 || t >= ARRAY_SIZE(perf_type_name))
+		return NULL;
+
+	return perf_type_name[t];
+}
+
+const char *libbpf_perf_hw_str(enum perf_hw_id t)
+{
+	if (t < 0 || t >= ARRAY_SIZE(perf_hw_name))
+		return NULL;
+
+	return perf_hw_name[t];
+}
+
+const char *libbpf_perf_hw_cache_str(enum perf_hw_cache_id t)
+{
+	if (t < 0 || t >= ARRAY_SIZE(perf_hw_cache_name))
+		return NULL;
+
+	return perf_hw_cache_name[t];
+}
+
+const char *libbpf_perf_hw_cache_op_str(enum perf_hw_cache_op_id t)
+{
+	if (t < 0 || t >= ARRAY_SIZE(perf_hw_cache_op_name))
+		return NULL;
+
+	return perf_hw_cache_op_name[t];
+}
+
+const char *
+libbpf_perf_hw_cache_op_result_str(enum perf_hw_cache_op_result_id t)
+{
+	if (t < 0 || t >= ARRAY_SIZE(perf_hw_cache_op_result_name))
+		return NULL;
+
+	return perf_hw_cache_op_result_name[t];
+}
+
+const char *libbpf_perf_sw_str(enum perf_sw_ids t)
+{
+	if (t < 0 || t >= ARRAY_SIZE(perf_sw_name))
+		return NULL;
+
+	return perf_sw_name[t];
+}
+
 const char *libbpf_bpf_link_type_str(enum bpf_link_type t)
 {
 	if (t < 0 || t >= ARRAY_SIZE(link_type_name))
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 754da73..4123e4c 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -16,6 +16,7 @@ 
 #include <stdbool.h>
 #include <sys/types.h>  // for size_t
 #include <linux/bpf.h>
+#include <linux/perf_event.h>
 
 #include "libbpf_common.h"
 #include "libbpf_legacy.h"
@@ -61,6 +62,61 @@  enum libbpf_errno {
 LIBBPF_API const char *libbpf_bpf_attach_type_str(enum bpf_attach_type t);
 
 /**
+ * @brief **libbpf_perf_type_str()** converts the provided perf type value
+ * into a textual representation.
+ * @param t The perf type.
+ * @return Pointer to a static string identifying the perf type. NULL is
+ * returned for unknown **perf_type_id** values.
+ */
+LIBBPF_API const char *libbpf_perf_type_str(enum perf_type_id t);
+
+/**
+ * @brief **libbpf_perf_hw_str()** converts the provided perf hw id
+ * into a textual representation.
+ * @param t The perf hw id.
+ * @return Pointer to a static string identifying the perf hw id. NULL is
+ * returned for unknown **perf_hw_id** values.
+ */
+LIBBPF_API const char *libbpf_perf_hw_str(enum perf_hw_id t);
+
+/**
+ * @brief **libbpf_perf_hw_cache_str()** converts the provided perf hw cache
+ * id into a textual representation.
+ * @param t The perf hw cache id.
+ * @return Pointer to a static string identifying the perf hw cache id.
+ * NULL is returned for unknown **perf_hw_cache_id** values.
+ */
+LIBBPF_API const char *libbpf_perf_hw_cache_str(enum perf_hw_cache_id t);
+
+/**
+ * @brief **libbpf_perf_hw_cache_op_str()** converts the provided perf hw
+ * cache op id into a textual representation.
+ * @param t The perf hw cache op id.
+ * @return Pointer to a static string identifying the perf hw cache op id.
+ * NULL is returned for unknown **perf_hw_cache_op_id** values.
+ */
+LIBBPF_API const char *libbpf_perf_hw_cache_op_str(enum perf_hw_cache_op_id t);
+
+/**
+ * @brief **libbpf_perf_hw_cache_op_result_str()** converts the provided
+ * perf hw cache op result id into a textual representation.
+ * @param t The perf hw cache op result id.
+ * @return Pointer to a static string identifying the perf hw cache op result
+ * id. NULL is returned for unknown **perf_hw_cache_op_result_id** values.
+ */
+LIBBPF_API const char *
+libbpf_perf_hw_cache_op_result_str(enum perf_hw_cache_op_result_id t);
+
+/**
+ * @brief **libbpf_perf_sw_str()** converts the provided perf sw id
+ * into a textual representation.
+ * @param t The perf sw id.
+ * @return Pointer to a static string identifying the perf sw id. NULL is
+ * returned for unknown **perf_sw_ids** values.
+ */
+LIBBPF_API const char *libbpf_perf_sw_str(enum perf_sw_ids t);
+
+/**
  * @brief **libbpf_bpf_link_type_str()** converts the provided link type value
  * into a textual representation.
  * @param t The link type.
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 7521a2f..6ae0a36 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -395,4 +395,10 @@  LIBBPF_1.2.0 {
 LIBBPF_1.3.0 {
 	global:
 		bpf_obj_pin_opts;
+		libbpf_perf_hw_cache_op_result_str;
+		libbpf_perf_hw_cache_op_str;
+		libbpf_perf_hw_cache_str;
+		libbpf_perf_hw_str;
+		libbpf_perf_sw_str;
+		libbpf_perf_type_str;
 } LIBBPF_1.2.0;