Skip to content

Commit 289b567

Browse files
robherringgregkh
authored andcommitted
perf: Skip and warn on unknown format 'configN' attrs
[ Upstream commit e552b7b ] 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 <[email protected]> Signed-off-by: Rob Herring <[email protected]> Tested-by: Leo Yan <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Clark <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 9d912a3 commit 289b567

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
@@ -373,6 +373,9 @@ __add_event(struct list_head *list, int *idx,
373373
struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) :
374374
cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
375375

376+
if (pmu)
377+
perf_pmu__warn_invalid_formats(pmu);
378+
376379
if (pmu && attr->type == PERF_TYPE_RAW)
377380
perf_pmu__warn_invalid_config(pmu, attr->config, name);
378381

tools/perf/util/pmu.c

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

1051+
void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu)
1052+
{
1053+
struct perf_pmu_format *format;
1054+
1055+
/* fake pmu doesn't have format list */
1056+
if (pmu == &perf_pmu__fake)
1057+
return;
1058+
1059+
list_for_each_entry(format, &pmu->format, list)
1060+
if (format->value >= PERF_PMU_FORMAT_VALUE_CONFIG_END) {
1061+
pr_warning("WARNING: '%s' format '%s' requires 'perf_event_attr::config%d'"
1062+
"which is not supported by this version of perf!\n",
1063+
pmu->name, format->name, format->value);
1064+
return;
1065+
}
1066+
}
1067+
10511068
static struct perf_pmu *pmu_find(const char *name)
10521069
{
10531070
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
@@ -135,6 +136,7 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu);
135136

136137
void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
137138
char *name);
139+
void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu);
138140

139141
bool perf_pmu__has_hybrid(void);
140142
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
@@ -20,7 +20,7 @@ do { \
2020

2121
%}
2222

23-
%token PP_CONFIG PP_CONFIG1 PP_CONFIG2
23+
%token PP_CONFIG
2424
%token PP_VALUE PP_ERROR
2525
%type <num> PP_VALUE
2626
%type <bits> bit_term
@@ -47,18 +47,11 @@ PP_CONFIG ':' bits
4747
$3));
4848
}
4949
|
50-
PP_CONFIG1 ':' bits
50+
PP_CONFIG PP_VALUE ':' bits
5151
{
5252
ABORT_ON(perf_pmu__new_format(format, name,
53-
PERF_PMU_FORMAT_VALUE_CONFIG1,
54-
$3));
55-
}
56-
|
57-
PP_CONFIG2 ':' bits
58-
{
59-
ABORT_ON(perf_pmu__new_format(format, name,
60-
PERF_PMU_FORMAT_VALUE_CONFIG2,
61-
$3));
53+
$2,
54+
$4));
6255
}
6356

6457
bits:

0 commit comments

Comments
 (0)