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 <yao.jin@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jin Yao <yao.jin@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.garry@huawei.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Link: http://lore.kernel.org/lkml/20210902065955.1299-3-yao.jin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Jin Yao 2021-09-02 14:59:55 +08:00 committed by Arnaldo Carvalho de Melo
parent 13d60ba073
commit c7a3828d98

View File

@ -9,6 +9,7 @@
#include "pmu-hybrid.h"
#include <dirent.h>
#include <errno.h>
#include "fncache.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@ -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;