From c7a3828d98db2730079265b5f51933dfcef8bb5f Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Thu, 2 Sep 2021 14:59:55 +0800 Subject: perf tests: Add test for PMU aliases A perf uncore PMU may have two PMU names, a real name and an alias. Add one test case to verify that the real and alias names have the same effect. Iterate sysfs to get one event which has an alias and create an evlist by adding two evsels. Evsel1 is created by event and evsel2 is created by alias. Test asserts: evsel1->core.attr.type == evsel2->core.attr.type evsel1->core.attr.config == evsel2->core.attr.config Signed-off-by: Jin Yao Reviewed-by: Andi Kleen Cc: Alexander Shishkin Cc: Jin Yao Cc: Jiri Olsa Cc: John Garry Cc: Kan Liang Cc: Peter Zijlstra Cc: Riccardo Mancini Link: http://lore.kernel.org/lkml/20210902065955.1299-3-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/parse-events.c | 92 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'tools') diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 8d4866739255..fd3556cc9ad4 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -9,6 +9,7 @@ #include "pmu-hybrid.h" #include #include +#include "fncache.h" #include #include #include @@ -2194,9 +2195,91 @@ static int test_pmu_events(void) return ret; } +static bool test_alias(char **event, char **alias) +{ + char path[PATH_MAX]; + DIR *dir; + struct dirent *dent; + const char *sysfs = sysfs__mountpoint(); + char buf[128]; + FILE *file; + + if (!sysfs) + return false; + + snprintf(path, PATH_MAX, "%s/bus/event_source/devices/", sysfs); + dir = opendir(path); + if (!dir) + return false; + + while ((dent = readdir(dir))) { + if (!strcmp(dent->d_name, ".") || + !strcmp(dent->d_name, "..")) + continue; + + snprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/alias", + sysfs, dent->d_name); + + if (!file_available(path)) + continue; + + file = fopen(path, "r"); + if (!file) + continue; + + if (!fgets(buf, sizeof(buf), file)) { + fclose(file); + continue; + } + + /* Remove the last '\n' */ + buf[strlen(buf) - 1] = 0; + + fclose(file); + *event = strdup(dent->d_name); + *alias = strdup(buf); + closedir(dir); + + if (*event == NULL || *alias == NULL) { + free(*event); + free(*alias); + return false; + } + + return true; + } + + closedir(dir); + return false; +} + +static int test__checkevent_pmu_events_alias(struct evlist *evlist) +{ + struct evsel *evsel1 = evlist__first(evlist); + struct evsel *evsel2 = evlist__last(evlist); + + TEST_ASSERT_VAL("wrong type", evsel1->core.attr.type == evsel2->core.attr.type); + TEST_ASSERT_VAL("wrong config", evsel1->core.attr.config == evsel2->core.attr.config); + return 0; +} + +static int test_pmu_events_alias(char *event, char *alias) +{ + struct evlist_test e = { .id = 0, }; + char name[2 * NAME_MAX + 20]; + + snprintf(name, sizeof(name), "%s/event=1/,%s/event=1/", + event, alias); + + e.name = name; + e.check = test__checkevent_pmu_events_alias; + return test_event(&e); +} + int test__parse_events(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret1, ret2 = 0; + char *event, *alias; #define TEST_EVENTS(tests) \ do { \ @@ -2221,6 +2304,15 @@ do { \ return ret; } + if (test_alias(&event, &alias)) { + int ret = test_pmu_events_alias(event, alias); + + free(event); + free(alias); + if (ret) + return ret; + } + ret1 = test_terms(test__terms, ARRAY_SIZE(test__terms)); if (!ret2) ret2 = ret1; -- cgit v1.2.3