From: Ian Rogers <irogers@google.com>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>,
Adrian Hunter <adrian.hunter@intel.com>,
James Clark <james.clark@linaro.org>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org
Cc: Ian Rogers <irogers@google.com>
Subject: [PATCH v1 05/14] perf test pmu-events: A sub-test per metric table
Date: Wed, 13 May 2026 16:04:41 -0700 [thread overview]
Message-ID: <20260513230450.529380-6-irogers@google.com> (raw)
In-Reply-To: <20260513230450.529380-1-irogers@google.com>
Break apart the slow "Parsing of PMU event table metrics" tests into
one pair of tests (real and fake PMU) per metric table found, storing
the specific table pointer in priv data.
Implement setup_pmu_events_suite() to dynamically allocate and populate
these test cases.
Split static parser tests out into a separate test__parsing_fake_static()
test case.
Update test__parsing() and test__parsing_fake() to retrieve the specific
table from priv data and test only that table, maintaining fallback
compatibility if priv is NULL.
Running these individual tests in parallel significantly reduces
overall test execution time.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/tests/pmu-events.c | 155 ++++++++++++++++++++++++++++++++--
1 file changed, 147 insertions(+), 8 deletions(-)
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
index a99716862168..56277737a824 100644
--- a/tools/perf/tests/pmu-events.c
+++ b/tools/perf/tests/pmu-events.c
@@ -903,13 +903,20 @@ static int test__parsing_callback(const struct pmu_metric *pm,
return err;
}
-static int test__parsing(struct test_suite *test __maybe_unused,
- int subtest __maybe_unused)
+static int test__parsing(struct test_suite *test, int subtest)
{
int failures = 0;
+ const struct pmu_metrics_table *table = NULL;
- pmu_for_each_core_metric(test__parsing_callback, &failures);
- pmu_for_each_sys_metric(test__parsing_callback, &failures);
+ if (test->test_cases)
+ table = test->test_cases[subtest].priv;
+
+ if (table) {
+ pmu_metrics_table__for_each_metric(table, test__parsing_callback, &failures);
+ } else {
+ pmu_for_each_core_metric(test__parsing_callback, &failures);
+ pmu_for_each_sys_metric(test__parsing_callback, &failures);
+ }
return failures == 0 ? TEST_OK : TEST_FAIL;
}
@@ -1000,8 +1007,8 @@ static int test__parsing_fake_callback(const struct pmu_metric *pm,
* Parse all the metrics for current architecture, or all defined cpus via the
* 'fake_pmu' in parse_events.
*/
-static int test__parsing_fake(struct test_suite *test __maybe_unused,
- int subtest __maybe_unused)
+static int test__parsing_fake_static(struct test_suite *test __maybe_unused,
+ int subtest __maybe_unused)
{
int err = 0;
@@ -1011,6 +1018,26 @@ static int test__parsing_fake(struct test_suite *test __maybe_unused,
return err;
}
+ return 0;
+}
+
+static int test__parsing_fake(struct test_suite *test, int subtest)
+{
+ int err = 0;
+ const struct pmu_metrics_table *table = NULL;
+
+ if (test->test_cases)
+ table = test->test_cases[subtest].priv;
+
+ if (table)
+ return pmu_metrics_table__for_each_metric(table, test__parsing_fake_callback, NULL);
+
+ for (size_t i = 0; i < ARRAY_SIZE(metrics); i++) {
+ err = metric_parse_fake("", metrics[i].str);
+ if (err)
+ return err;
+ }
+
err = pmu_for_each_core_metric(test__parsing_fake_callback, NULL);
if (err)
return err;
@@ -1039,17 +1066,129 @@ static int test__parsing_threshold(struct test_suite *test __maybe_unused,
return pmu_for_each_sys_metric(test__parsing_threshold_callback, NULL);
}
+struct populate_cb_data {
+ struct test_case *test_cases;
+ size_t curr;
+};
+
+static int count_metrics_tables_cb(const struct pmu_metrics_table *table __maybe_unused, void *data)
+{
+ size_t *count = data;
+ (*count)++;
+ return 0;
+}
+
+static int populate_metrics_tables_cb(const struct pmu_metrics_table *table, void *data)
+{
+ struct populate_cb_data *cb_data = data;
+ const char *table_name = pmu_metrics_table__name(table);
+ char *desc_real, *desc_fake;
+
+ if (!table_name)
+ table_name = "unknown";
+
+ if (asprintf(&desc_real, "PMU metric parsing: %s", table_name) < 0)
+ return -ENOMEM;
+ if (asprintf(&desc_fake, "PMU metric parsing with fake PMU: %s", table_name) < 0) {
+ free(desc_real);
+ return -ENOMEM;
+ }
+
+ cb_data->test_cases[cb_data->curr++] = (struct test_case){
+ .name = "parsing",
+ .desc = desc_real,
+ .run_case = test__parsing,
+ .priv = (void *)table,
+ .skip_reason = "some metrics failed",
+ };
+
+ cb_data->test_cases[cb_data->curr++] = (struct test_case){
+ .name = "parsing_fake",
+ .desc = desc_fake,
+ .run_case = test__parsing_fake,
+ .priv = (void *)table,
+ };
+
+ return 0;
+}
+
+static struct test_case pmu_events_tests[];
+
+static int setup_pmu_events_suite(struct test_suite *suite)
+{
+ size_t num_tables = 0;
+ size_t num_fixed_tests = 4;
+ size_t tests_per_table = 2;
+ size_t total_tests;
+ struct test_case *test_cases;
+ size_t curr = 0;
+ struct populate_cb_data cb_data;
+ int ret;
+
+ if (suite->test_cases != pmu_events_tests)
+ return 0;
+
+ ret = pmu_metrics_table__for_each_table(count_metrics_tables_cb, &num_tables);
+ if (ret)
+ return ret;
+
+ total_tests = num_fixed_tests + (num_tables * tests_per_table) + 1;
+
+ test_cases = calloc(total_tests, sizeof(*test_cases));
+ if (!test_cases)
+ return -ENOMEM;
+
+ test_cases[curr++] = (struct test_case){
+ .name = "pmu_event_table",
+ .desc = "PMU event table sanity",
+ .run_case = test__pmu_event_table,
+ };
+ test_cases[curr++] = (struct test_case){
+ .name = "aliases",
+ .desc = "PMU event map aliases",
+ .run_case = test__aliases,
+ };
+ test_cases[curr++] = (struct test_case){
+ .name = "parsing_fake_static",
+ .desc = "Parsing of static metrics with fake PMU",
+ .run_case = test__parsing_fake_static,
+ };
+ test_cases[curr++] = (struct test_case){
+ .name = "parsing_threshold",
+ .desc = "Parsing of metric thresholds with fake PMU",
+ .run_case = test__parsing_threshold,
+ };
+
+ cb_data = (struct populate_cb_data){
+ .test_cases = test_cases,
+ .curr = curr,
+ };
+
+ ret = pmu_metrics_table__for_each_table(populate_metrics_tables_cb, &cb_data);
+ if (ret) {
+ size_t i;
+ for (i = num_fixed_tests; i < cb_data.curr; i++)
+ free((char *)test_cases[i].desc);
+ free(test_cases);
+ return ret;
+ }
+
+ suite->test_cases = test_cases;
+ return 0;
+}
+
static struct test_case pmu_events_tests[] = {
TEST_CASE("PMU event table sanity", pmu_event_table),
TEST_CASE("PMU event map aliases", aliases),
TEST_CASE_REASON("Parsing of PMU event table metrics", parsing,
"some metrics failed"),
- TEST_CASE("Parsing of PMU event table metrics with fake PMUs", parsing_fake),
- TEST_CASE("Parsing of metric thresholds with fake PMUs", parsing_threshold),
+ TEST_CASE("Parsing of PMU event table metrics with fake PMU", parsing_fake),
+ TEST_CASE("Parsing of metric thresholds with fake PMU", parsing_threshold),
{ .name = NULL, }
};
struct test_suite suite__pmu_events = {
.desc = "PMU JSON event tests",
.test_cases = pmu_events_tests,
+ .setup = setup_pmu_events_suite,
};
--
2.54.0.563.g4f69b47b94-goog
next prev parent reply other threads:[~2026-05-13 23:05 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-13 23:04 [PATCH v1 00/14] perf test: Harness improvements Ian Rogers
2026-05-13 23:04 ` [PATCH v1 01/14] perf jevents.py: Make generated C code more kernel style Ian Rogers
2026-05-13 23:04 ` [PATCH v1 02/14] perf pmu-events: Add API to get metric table name and iterate tables Ian Rogers
2026-05-13 23:04 ` [PATCH v1 03/14] perf test: Drain pipe after child finishes to avoid losing output Ian Rogers
2026-05-13 23:04 ` [PATCH v1 04/14] perf test: Support dynamic test suites with setup callback and private data Ian Rogers
2026-05-13 23:04 ` Ian Rogers [this message]
2026-05-13 23:04 ` [PATCH v1 06/14] perf test: Refactor parallel poll loop to drain all pipes simultaneously Ian Rogers
2026-05-13 23:04 ` [PATCH v1 07/14] perf test: Show snippet failure output for verbose=1 Ian Rogers
2026-05-13 23:04 ` [PATCH v1 08/14] perf test: Add summary reporting Ian Rogers
2026-05-13 23:04 ` [PATCH v1 09/14] perf test: Fix subtest status alignment for multi-digit indexes Ian Rogers
2026-05-13 23:04 ` [PATCH v1 10/14] perf test: Skip shebang and SPDX comments in shell test descriptions Ian Rogers
2026-05-13 23:04 ` [PATCH v1 11/14] perf test: Split monolithic 'util' test suite into sub-tests Ian Rogers
2026-05-13 23:04 ` [PATCH v1 12/14] perf test: Add -j/--junit option for JUnit XML test reports Ian Rogers
2026-05-13 23:04 ` [PATCH v1 13/14] perf test: Add shell test to validate JUnit XML reporting output Ian Rogers
2026-05-13 23:04 ` [PATCH v1 14/14] perf test: Remove /usr/bin/cc dependency from Intel PT shell test Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260513230450.529380-6-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox