Skip to content

Commit e552b7b

Browse files
robherringacmel
authored andcommitted
perf: Skip and warn on unknown format 'configN' attrs
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: 'arm_spe_0' format 'inv_event_filter' requires 'perf_event_attr::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. Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Rob Herring <robh@kernel.org> Tested-by: Leo Yan <leo.yan@linaro.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220914-arm-perf-tool-spe1-2-v2-v4-1-83c098e6212e@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 0cef141 commit e552b7b

File tree

5 files changed

+26
-13
lines changed

5 files changed

+26
-13
lines changed

tools/perf/util/parse-events.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ __add_event(struct list_head *list, int *idx,
246246
struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) :
247247
cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
248248

249+
if (pmu)
250+
perf_pmu__warn_invalid_formats(pmu);
251+
249252
if (pmu && attr->type == PERF_TYPE_RAW)
250253
perf_pmu__warn_invalid_config(pmu, attr->config, name);
251254

tools/perf/util/pmu.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,23 @@ static struct perf_pmu *pmu_lookup(const char *lookup_name)
10051005
return NULL;
10061006
}
10071007

1008+
void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu)
1009+
{
1010+
struct perf_pmu_format *format;
1011+
1012+
/* fake pmu doesn't have format list */
1013+
if (pmu == &perf_pmu__fake)
1014+
return;
1015+
1016+
list_for_each_entry(format, &pmu->format, list)
1017+
if (format->value >= PERF_PMU_FORMAT_VALUE_CONFIG_END) {
1018+
pr_warning("WARNING: '%s' format '%s' requires 'perf_event_attr::config%d'"
1019+
"which is not supported by this version of perf!\n",
1020+
pmu->name, format->name, format->value);
1021+
return;
1022+
}
1023+
}
1024+
10081025
static struct perf_pmu *pmu_find(const char *name)
10091026
{
10101027
struct perf_pmu *pmu;

tools/perf/util/pmu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ enum {
1717
PERF_PMU_FORMAT_VALUE_CONFIG,
1818
PERF_PMU_FORMAT_VALUE_CONFIG1,
1919
PERF_PMU_FORMAT_VALUE_CONFIG2,
20+
PERF_PMU_FORMAT_VALUE_CONFIG_END,
2021
};
2122

2223
#define PERF_PMU_FORMAT_BITS 64
@@ -139,6 +140,7 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu);
139140

140141
void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
141142
const char *name);
143+
void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu);
142144

143145
bool perf_pmu__has_hybrid(void);
144146
int perf_pmu__match(char *pattern, char *name, char *tok);

tools/perf/util/pmu.l

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ num_dec [0-9]+
2727

2828
{num_dec} { return value(10); }
2929
config { return PP_CONFIG; }
30-
config1 { return PP_CONFIG1; }
31-
config2 { return PP_CONFIG2; }
3230
- { return '-'; }
3331
: { return ':'; }
3432
, { return ','; }

tools/perf/util/pmu.y

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ do { \
1818

1919
%}
2020

21-
%token PP_CONFIG PP_CONFIG1 PP_CONFIG2
21+
%token PP_CONFIG
2222
%token PP_VALUE PP_ERROR
2323
%type <num> PP_VALUE
2424
%type <bits> bit_term
@@ -45,18 +45,11 @@ PP_CONFIG ':' bits
4545
$3));
4646
}
4747
|
48-
PP_CONFIG1 ':' bits
48+
PP_CONFIG PP_VALUE ':' bits
4949
{
5050
ABORT_ON(perf_pmu__new_format(format, name,
51-
PERF_PMU_FORMAT_VALUE_CONFIG1,
52-
$3));
53-
}
54-
|
55-
PP_CONFIG2 ':' bits
56-
{
57-
ABORT_ON(perf_pmu__new_format(format, name,
58-
PERF_PMU_FORMAT_VALUE_CONFIG2,
59-
$3));
51+
$2,
52+
$4));
6053
}
6154

6255
bits:

0 commit comments

Comments
 (0)