Messages in this thread Patch in this message | | | From | Rob Herring <> | Subject | [PATCH v2] perf: Skip and warn on unknown format 'configN' attrs | Date | Fri, 9 Sep 2022 15:45:09 -0500 |
| |
If the kernel exposes a new perf_event_attr field in a format attr, perf will return an error stating the specified PMU can't be found. For example, a format attr with 'config3:0-63' causes an error as config3 is unknown to perf. This causes a compatibility issue between a newer kernel with older perf tool.
Before this change with a kernel adding 'config3' I get:
$ perf record -e arm_spe// -- true event syntax error: 'arm_spe//' \___ Cannot find PMU `arm_spe'. Missing kernel support? Run 'perf list' for a list of valid events
Usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>]
-e, --event <event> event selector. use 'perf list' to list available events
After this change, I get:
$ perf record -e arm_spe// -- true WARNING: format 'inv_event_filter' requires 'config3' which is not supported by this version of perf! [ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.091 MB perf.data ]
To support unknown configN formats, rework the YACC implementation to pass any config[0-9]+ format to perf_pmu__new_format() to handle with a warning.
Note that the user will get the warning if *any* PMU has an unsupported format attr even if that PMU isn't used. This is because perf tool scans all the PMUs.
Signed-off-by: Rob Herring <robh@kernel.org> --- v2: - Rework YACC code to handle configN formats in C code - Add a warning when an unknown configN attr is found
v1: https://lore.kernel.org/all/20220901184709.2179309-1-robh@kernel.org/ --- tools/perf/util/pmu.c | 6 ++++++ tools/perf/util/pmu.l | 2 -- tools/perf/util/pmu.y | 15 ++++----------- 3 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 89655d53117a..6757db7d559c 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1475,6 +1475,12 @@ int perf_pmu__new_format(struct list_head *list, char *name, { struct perf_pmu_format *format; + if (config > PERF_PMU_FORMAT_VALUE_CONFIG2) { + pr_warning("WARNING: format '%s' requires 'config%d' which is not supported by this version of perf!\n", + name, config); + return 0; + } + format = zalloc(sizeof(*format)); if (!format) return -ENOMEM; diff --git a/tools/perf/util/pmu.l b/tools/perf/util/pmu.l index a15d9fbd7c0e..58b4926cfaca 100644 --- a/tools/perf/util/pmu.l +++ b/tools/perf/util/pmu.l @@ -27,8 +27,6 @@ num_dec [0-9]+ {num_dec} { return value(10); } config { return PP_CONFIG; } -config1 { return PP_CONFIG1; } -config2 { return PP_CONFIG2; } - { return '-'; } : { return ':'; } , { return ','; } diff --git a/tools/perf/util/pmu.y b/tools/perf/util/pmu.y index bfd7e8509869..283efe059819 100644 --- a/tools/perf/util/pmu.y +++ b/tools/perf/util/pmu.y @@ -20,7 +20,7 @@ do { \ %} -%token PP_CONFIG PP_CONFIG1 PP_CONFIG2 +%token PP_CONFIG %token PP_VALUE PP_ERROR %type <num> PP_VALUE %type <bits> bit_term @@ -47,18 +47,11 @@ PP_CONFIG ':' bits $3)); } | -PP_CONFIG1 ':' bits +PP_CONFIG PP_VALUE ':' bits { ABORT_ON(perf_pmu__new_format(format, name, - PERF_PMU_FORMAT_VALUE_CONFIG1, - $3)); -} -| -PP_CONFIG2 ':' bits -{ - ABORT_ON(perf_pmu__new_format(format, name, - PERF_PMU_FORMAT_VALUE_CONFIG2, - $3)); + $2, + $4)); } bits: -- 2.34.1
| |