[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2649abddcb741de5d376514aebc32239d35c41dc.camel@intel.com>
Date: Wed, 5 Mar 2025 21:39:58 +0000
From: "Falcon, Thomas" <thomas.falcon@...el.com>
To: "alexander.shishkin@...ux.intel.com" <alexander.shishkin@...ux.intel.com>,
"ak@...ux.intel.com" <ak@...ux.intel.com>, "Hunter, Adrian"
<adrian.hunter@...el.com>, "linux-kernel@...r.kernel.org"
<linux-kernel@...r.kernel.org>, "asmadeus@...ewreck.org"
<asmadeus@...ewreck.org>, "linux-perf-users@...r.kernel.org"
<linux-perf-users@...r.kernel.org>, "irogers@...gle.com"
<irogers@...gle.com>, "mingo@...hat.com" <mingo@...hat.com>,
"james.clark@...aro.org" <james.clark@...aro.org>,
"kan.liang@...ux.intel.com" <kan.liang@...ux.intel.com>,
"mark.rutland@....com" <mark.rutland@....com>, "peterz@...radead.org"
<peterz@...radead.org>, "dapeng1.mi@...ux.intel.com"
<dapeng1.mi@...ux.intel.com>, "acme@...nel.org" <acme@...nel.org>,
"jolsa@...nel.org" <jolsa@...nel.org>, "namhyung@...nel.org"
<namhyung@...nel.org>
Subject: Re: [PATCH v1 1/2] perf tools: Improve handling of hybrid PMUs in
perf_event_attr__fprintf
On Wed, 2025-03-05 at 00:37 -0800, Ian Rogers wrote:
> Support the PMU name from the legacy hardware and hw_cache PMU
> extended types. Remove some macros and make variables more intention
> revealing, rather than just being called "value".
>
> Before:
> ```
> $ perf stat -vv -e instructions true
> ...
> ------------------------------------------------------------
> perf_event_attr:
> type 0 (PERF_TYPE_HARDWARE)
> size 136
> config 0xa00000001
> sample_type IDENTIFIER
> read_format
> TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
> disabled 1
> inherit 1
> enable_on_exec 1
> exclude_guest 1
> ------------------------------------------------------------
> sys_perf_event_open: pid 181636 cpu -1 group_fd -1 flags 0x8 = 5
> ------------------------------------------------------------
> perf_event_attr:
> type 0 (PERF_TYPE_HARDWARE)
> size 136
> config 0x400000001
> sample_type IDENTIFIER
> read_format
> TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
> disabled 1
> inherit 1
> enable_on_exec 1
> exclude_guest 1
> ------------------------------------------------------------
> sys_perf_event_open: pid 181636 cpu -1 group_fd -1 flags 0x8 = 6
> ...
> ```
>
> After:
> ```
> $ perf stat -vv -e instructions true
> ...
> ------------------------------------------------------------
> perf_event_attr:
> type 0 (PERF_TYPE_HARDWARE)
> size 136
> config 0xa00000001
> (cpu_atom/PERF_COUNT_HW_INSTRUCTIONS/)
> sample_type IDENTIFIER
> read_format
> TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
> disabled 1
> inherit 1
> enable_on_exec 1
> ------------------------------------------------------------
> sys_perf_event_open: pid 181724 cpu -1 group_fd -1 flags 0x8 = 5
> ------------------------------------------------------------
> perf_event_attr:
> type 0 (PERF_TYPE_HARDWARE)
> size 136
> config 0x400000001
> (cpu_core/PERF_COUNT_HW_INSTRUCTIONS/)
> sample_type IDENTIFIER
> read_format
> TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
> disabled 1
> inherit 1
> enable_on_exec 1
> ------------------------------------------------------------
> sys_perf_event_open: pid 181724 cpu -1 group_fd -1 flags 0x8 = 6
> ...
> ```
>
> Signed-off-by: Ian Rogers <irogers@...gle.com>
Tested on an Alder Lake.
Tested-by: Thomas Falcon <thomas.falcon@...el.com>
> ---
> tools/perf/util/perf_event_attr_fprintf.c | 124 +++++++++++++-------
> --
> 1 file changed, 75 insertions(+), 49 deletions(-)
>
> diff --git a/tools/perf/util/perf_event_attr_fprintf.c
> b/tools/perf/util/perf_event_attr_fprintf.c
> index c7f3543b9921..66b666d9ce64 100644
> --- a/tools/perf/util/perf_event_attr_fprintf.c
> +++ b/tools/perf/util/perf_event_attr_fprintf.c
> @@ -79,24 +79,22 @@ static void __p_read_format(char *buf, size_t
> size, u64 value)
> #define ENUM_ID_TO_STR_CASE(x) case x: return (#x);
> static const char *stringify_perf_type_id(struct perf_pmu *pmu, u32
> type)
> {
> - if (pmu)
> - return pmu->name;
> -
> switch (type) {
> ENUM_ID_TO_STR_CASE(PERF_TYPE_HARDWARE)
> ENUM_ID_TO_STR_CASE(PERF_TYPE_SOFTWARE)
> ENUM_ID_TO_STR_CASE(PERF_TYPE_TRACEPOINT)
> ENUM_ID_TO_STR_CASE(PERF_TYPE_HW_CACHE)
> - ENUM_ID_TO_STR_CASE(PERF_TYPE_RAW)
> ENUM_ID_TO_STR_CASE(PERF_TYPE_BREAKPOINT)
> + case PERF_TYPE_RAW:
> + return pmu ? pmu->name : "PERF_TYPE_RAW";
> default:
> - return NULL;
> + return pmu ? pmu->name : NULL;
> }
> }
>
> static const char *stringify_perf_hw_id(u64 value)
> {
> - switch (value) {
> + switch (value & PERF_HW_EVENT_MASK) {
> ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CPU_CYCLES)
> ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_INSTRUCTIONS)
> ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_REFERENCES)
> @@ -169,79 +167,100 @@ static const char *stringify_perf_sw_id(u64
> value)
> }
> #undef ENUM_ID_TO_STR_CASE
>
> -#define PRINT_ID(_s, _f) \
> -do { \
> - const char *__s = _s; \
> - if (__s == NULL) \
> - snprintf(buf, size, _f,
> value); \
> - else \
> - snprintf(buf, size, _f" (%s)", value, __s); \
> -} while (0)
> -#define print_id_unsigned(_s) PRINT_ID(_s, "%"PRIu64)
> -#define print_id_hex(_s) PRINT_ID(_s, "%#"PRIx64)
> +static void print_id_unsigned(char *buf, size_t size, u64 value,
> const char *s)
> +{
> + if (s == NULL)
> + snprintf(buf, size, "%"PRIu64, value);
> + else
> + snprintf(buf, size, "%"PRIu64" (%s)", value, s);
> +}
> +
> +static void print_id_hex(char *buf, size_t size, u64 value, const
> char *s)
> +{
> + if (s == NULL)
> + snprintf(buf, size, "%#"PRIx64, value);
> + else
> + snprintf(buf, size, "%#"PRIx64" (%s)", value, s);
> +}
>
> -static void __p_type_id(struct perf_pmu *pmu, char *buf, size_t
> size, u64 value)
> +static void __p_type_id(char *buf, size_t size, struct perf_pmu
> *pmu, u32 type)
> {
> - print_id_unsigned(stringify_perf_type_id(pmu, value));
> + print_id_unsigned(buf, size, type,
> stringify_perf_type_id(pmu, type));
> }
>
> -static void __p_config_hw_id(char *buf, size_t size, u64 value)
> +static void __p_config_hw_id(char *buf, size_t size, struct perf_pmu
> *pmu, u64 config)
> {
> - print_id_hex(stringify_perf_hw_id(value));
> + const char *name = stringify_perf_hw_id(config);
> +
> + if (name == NULL) {
> + if (pmu == NULL) {
> + snprintf(buf, size, "%#"PRIx64, config);
> + } else {
> + snprintf(buf, size, "%#"PRIx64"
> (%s/config=%#"PRIx64"/)", config, pmu->name,
> + config);
> + }
> + } else {
> + if (pmu == NULL)
> + snprintf(buf, size, "%#"PRIx64" (%s)",
> config, name);
> + else
> + snprintf(buf, size, "%#"PRIx64" (%s/%s/)",
> config, pmu->name, name);
> + }
> }
>
> -static void __p_config_sw_id(char *buf, size_t size, u64 value)
> +static void __p_config_sw_id(char *buf, size_t size, u64 id)
> {
> - print_id_hex(stringify_perf_sw_id(value));
> + print_id_hex(buf, size, id, stringify_perf_sw_id(id));
> }
>
> -static void __p_config_hw_cache_id(char *buf, size_t size, u64
> value)
> +static void __p_config_hw_cache_id(char *buf, size_t size, struct
> perf_pmu *pmu, u64 config)
> {
> - const char *hw_cache_str = stringify_perf_hw_cache_id(value
> & 0xff);
> + const char *hw_cache_str = stringify_perf_hw_cache_id(config
> & 0xff);
> const char *hw_cache_op_str =
> - stringify_perf_hw_cache_op_id((value & 0xff00) >>
> 8);
> + stringify_perf_hw_cache_op_id((config & 0xff00) >>
> 8);
> const char *hw_cache_op_result_str =
> - stringify_perf_hw_cache_op_result_id((value &
> 0xff0000) >> 16);
> -
> - if (hw_cache_str == NULL || hw_cache_op_str == NULL ||
> - hw_cache_op_result_str == NULL) {
> - snprintf(buf, size, "%#"PRIx64, value);
> + stringify_perf_hw_cache_op_result_id((config &
> 0xff0000) >> 16);
> +
> + if (hw_cache_str == NULL || hw_cache_op_str == NULL ||
> hw_cache_op_result_str == NULL) {
> + if (pmu == NULL) {
> + snprintf(buf, size, "%#"PRIx64, config);
> + } else {
> + snprintf(buf, size, "%#"PRIx64"
> (%s/config=%#"PRIx64"/)", config, pmu->name,
> + config);
> + }
> } else {
> - snprintf(buf, size, "%#"PRIx64" (%s | %s | %s)",
> value,
> - hw_cache_op_result_str, hw_cache_op_str,
> hw_cache_str);
> + if (pmu == NULL) {
> + snprintf(buf, size, "%#"PRIx64" (%s | %s |
> %s)", config,
> + hw_cache_op_result_str,
> hw_cache_op_str, hw_cache_str);
> + } else {
> + snprintf(buf, size, "%#"PRIx64" (%s/%s | %s
> | %s/)", config, pmu->name,
> + hw_cache_op_result_str,
> hw_cache_op_str, hw_cache_str);
> + }
> }
> }
>
> -static void __p_config_tracepoint_id(char *buf, size_t size, u64
> value)
> +static void __p_config_tracepoint_id(char *buf, size_t size, u64 id)
> {
> - char *str = tracepoint_id_to_name(value);
> + char *str = tracepoint_id_to_name(id);
>
> - print_id_hex(str);
> + print_id_hex(buf, size, id, str);
> free(str);
> }
>
> -static void __p_config_id(struct perf_pmu *pmu, char *buf, size_t
> size, u32 type, u64 value)
> +static void __p_config_id(struct perf_pmu *pmu, char *buf, size_t
> size, u32 type, u64 config)
> {
> - const char *name = perf_pmu__name_from_config(pmu, value);
> -
> - if (name) {
> - print_id_hex(name);
> - return;
> - }
> switch (type) {
> case PERF_TYPE_HARDWARE:
> - return __p_config_hw_id(buf, size, value);
> + return __p_config_hw_id(buf, size, pmu, config);
> case PERF_TYPE_SOFTWARE:
> - return __p_config_sw_id(buf, size, value);
> + return __p_config_sw_id(buf, size, config);
> case PERF_TYPE_HW_CACHE:
> - return __p_config_hw_cache_id(buf, size, value);
> + return __p_config_hw_cache_id(buf, size, pmu,
> config);
> case PERF_TYPE_TRACEPOINT:
> - return __p_config_tracepoint_id(buf, size, value);
> + return __p_config_tracepoint_id(buf, size, config);
> case PERF_TYPE_RAW:
> case PERF_TYPE_BREAKPOINT:
> default:
> - snprintf(buf, size, "%#"PRIx64, value);
> - return;
> + return print_id_hex(buf, size, config,
> perf_pmu__name_from_config(pmu, config));
> }
> }
>
> @@ -253,7 +272,7 @@ static void __p_config_id(struct perf_pmu *pmu,
> char *buf, size_t size, u32 type
> #define p_sample_type(val) __p_sample_type(buf, BUF_SIZE, val)
> #define p_branch_sample_type(val) __p_branch_sample_type(buf,
> BUF_SIZE, val)
> #define p_read_format(val) __p_read_format(buf, BUF_SIZE, val)
> -#define p_type_id(val) __p_type_id(pmu, buf, BUF_SIZE, val)
> +#define p_type_id(val) __p_type_id(buf, BUF_SIZE, pmu, val)
> #define p_config_id(val) __p_config_id(pmu, buf, BUF_SIZE,
> attr->type, val)
>
> #define PRINT_ATTRn(_n, _f, _p, _a) \
> @@ -273,6 +292,13 @@ int perf_event_attr__fprintf(FILE *fp, struct
> perf_event_attr *attr,
> char buf[BUF_SIZE];
> int ret = 0;
>
> + if (!pmu && (attr->type == PERF_TYPE_HARDWARE || attr->type
> == PERF_TYPE_HW_CACHE)) {
> + u32 extended_type = attr->config >>
> PERF_PMU_TYPE_SHIFT;
> +
> + if (extended_type)
> + pmu =
> perf_pmus__find_by_type(extended_type);
> + }
> +
> PRINT_ATTRn("type", type, p_type_id, true);
> PRINT_ATTRf(size, p_unsigned);
> PRINT_ATTRn("config", config, p_config_id, true);
Powered by blists - more mailing lists