aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Rogers <[email protected]>2024-05-02 14:35:06 -0700
committerArnaldo Carvalho de Melo <[email protected]>2024-05-03 17:08:20 -0300
commit6debc5aa326fa2eefe2988aaa4c46a1aa6b16e11 (patch)
tree6cce258f2500afadebe079805ebc6a3c07620cb8
parent18eb2ca8c18f0612c15aa12375e7cba29e97ab1a (diff)
perf test pmu: Test all sysfs PMU event names are the same case
Being either lower or upper case means event name probes can avoid scanning the directory doing case insensitive comparisons, just the lower or upper case version of the name can be checked for existence. For the majority of PMUs event names are all lower case, upper case names are present on S390. Reviewed-by: Kan Liang <[email protected]> Signed-off-by: Ian Rogers <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Bjorn Helgaas <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Clark <[email protected]> Cc: Jing Zhang <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Randy Dunlap <[email protected]> Cc: Ravi Bangoria <[email protected]> Cc: Thomas Richter <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
-rw-r--r--tools/perf/tests/pmu.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c
index 071cfc51b52c..06cc0e46cb28 100644
--- a/tools/perf/tests/pmu.c
+++ b/tools/perf/tests/pmu.c
@@ -5,12 +5,17 @@
#include "pmu.h"
#include "tests.h"
#include "debug.h"
+#include "fncache.h"
+#include <api/fs/fs.h>
+#include <ctype.h>
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <sys/types.h>
/* Fake PMUs created in temp directory. */
static LIST_HEAD(test_pmus);
@@ -251,9 +256,94 @@ err_out:
return ret;
}
+static bool permitted_event_name(const char *name)
+{
+ bool has_lower = false, has_upper = false;
+
+ for (size_t i = 0; i < strlen(name); i++) {
+ char c = name[i];
+
+ if (islower(c)) {
+ if (has_upper)
+ return false;
+ has_lower = true;
+ continue;
+ }
+ if (isupper(c)) {
+ if (has_lower)
+ return false;
+ has_upper = true;
+ continue;
+ }
+ if (!isdigit(c) && c != '.' && c != '_' && c != '-')
+ return false;
+ }
+ return true;
+}
+
+static int test__pmu_event_names(struct test_suite *test __maybe_unused,
+ int subtest __maybe_unused)
+{
+ char path[PATH_MAX];
+ DIR *pmu_dir, *event_dir;
+ struct dirent *pmu_dent, *event_dent;
+ const char *sysfs = sysfs__mountpoint();
+ int ret = TEST_OK;
+
+ if (!sysfs) {
+ pr_err("Sysfs not mounted\n");
+ return TEST_FAIL;
+ }
+
+ snprintf(path, sizeof(path), "%s/bus/event_source/devices/", sysfs);
+ pmu_dir = opendir(path);
+ if (!pmu_dir) {
+ pr_err("Error opening \"%s\"\n", path);
+ return TEST_FAIL;
+ }
+ while ((pmu_dent = readdir(pmu_dir))) {
+ if (!strcmp(pmu_dent->d_name, ".") ||
+ !strcmp(pmu_dent->d_name, ".."))
+ continue;
+
+ snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/type",
+ sysfs, pmu_dent->d_name);
+
+ /* Does it look like a PMU? */
+ if (!file_available(path))
+ continue;
+
+ /* Process events. */
+ snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/events",
+ sysfs, pmu_dent->d_name);
+
+ event_dir = opendir(path);
+ if (!event_dir) {
+ pr_debug("Skipping as no event directory \"%s\"\n", path);
+ continue;
+ }
+ while ((event_dent = readdir(event_dir))) {
+ const char *event_name = event_dent->d_name;
+
+ if (!strcmp(event_name, ".") || !strcmp(event_name, ".."))
+ continue;
+
+ if (!permitted_event_name(event_name)) {
+ pr_err("Invalid sysfs event name: %s/%s\n",
+ pmu_dent->d_name, event_name);
+ ret = TEST_FAIL;
+ }
+ }
+ closedir(event_dir);
+ }
+ closedir(pmu_dir);
+ return ret;
+}
+
static struct test_case tests__pmu[] = {
TEST_CASE("Parsing with PMU format directory", pmu_format),
TEST_CASE("Parsing with PMU event", pmu_events),
+ TEST_CASE("PMU event names", pmu_event_names),
{ .name = NULL, }
};