perf pmu: Skip test on Arm64 when #slots is zero

Some Arm64 PMUs expose 'caps/slots' as 0 when the slot count is not
implemented, tool_pmu__read_event() currently returns false for this,
so metrics that reference #slots are reported as syntax error.

Since the commit 3a61fd866e ("perf expr: Return -EINVAL for syntax
error in expr__find_ids()"), these syntax errors are populated as
failures and make the PMU metric test fail:

    9.3: Parsing of PMU event table metrics:
    --- start ---
    ...

    Found metric 'backend_bound'
    metric expr 100 * (stall_slot_backend / (#slots * cpu_cycles)) for backend_bound
    parsing metric: 100 * (stall_slot_backend / (#slots * cpu_cycles))
    Failure to read '#slots'
    literal: #slots = nan
    syntax error
    Fail to parse metric or group `backend_bound'

    ...
    ---- end(-1) ----
    9.3: Parsing of PMU event table metrics    : FAILED!

This commit introduces a new function is_expected_broken_metric() to
identify broken metrics, and treats metrics containing "#slots" as
expected broken when #slots == 0 on Arm64 platforms.

Fixes: 3a61fd866e ("perf expr: Return -EINVAL for syntax error in expr__find_ids()")
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Leo Yan
2026-04-10 12:13:44 +01:00
committed by Arnaldo Carvalho de Melo
parent 7ee7f48413
commit 2e2ba7d1ea

View File

@@ -15,6 +15,7 @@
#include "util/expr.h"
#include "util/hashmap.h"
#include "util/parse-events.h"
#include "util/tool_pmu.h"
#include "metricgroup.h"
#include "stat.h"
@@ -817,6 +818,26 @@ struct metric {
struct metric_ref metric_ref;
};
static bool is_expected_broken_metric(const struct pmu_metric *pm)
{
if (!strcmp(pm->metric_name, "M1") || !strcmp(pm->metric_name, "M2") ||
!strcmp(pm->metric_name, "M3"))
return true;
#if defined(__aarch64__)
/*
* Arm64 platforms may return "#slots == 0", which is treated as a
* syntax error by the parser. Don't test these metrics when running
* on such platforms.
*/
if (strstr(pm->metric_expr, "#slots") &&
!tool_pmu__cpu_slots_per_cycle())
return true;
#endif
return false;
}
static int test__parsing_callback(const struct pmu_metric *pm,
const struct pmu_metrics_table *table,
void *data)
@@ -852,8 +873,7 @@ static int test__parsing_callback(const struct pmu_metric *pm,
err = metricgroup__parse_groups_test(evlist, table, pm->metric_name);
if (err) {
if (!strcmp(pm->metric_name, "M1") || !strcmp(pm->metric_name, "M2") ||
!strcmp(pm->metric_name, "M3")) {
if (is_expected_broken_metric(pm)) {
(*failures)--;
pr_debug("Expected broken metric %s skipping\n", pm->metric_name);
err = 0;