Skip to content

Commit 6debc5a

Browse files
captain5050acmel
authored andcommitted
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 <kan.liang@linux.intel.com> Signed-off-by: Ian Rogers <irogers@google.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jing Zhang <renyu.zj@linux.alibaba.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Thomas Richter <tmricht@linux.ibm.com> Link: https://lore.kernel.org/r/20240502213507.2339733-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 18eb2ca commit 6debc5a

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

tools/perf/tests/pmu.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55
#include "pmu.h"
66
#include "tests.h"
77
#include "debug.h"
8+
#include "fncache.h"
9+
#include <api/fs/fs.h>
10+
#include <ctype.h>
11+
#include <dirent.h>
812
#include <errno.h>
913
#include <fcntl.h>
1014
#include <stdio.h>
1115
#include <stdlib.h>
1216
#include <unistd.h>
1317
#include <sys/stat.h>
18+
#include <sys/types.h>
1419

1520
/* Fake PMUs created in temp directory. */
1621
static LIST_HEAD(test_pmus);
@@ -251,9 +256,94 @@ static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest
251256
return ret;
252257
}
253258

259+
static bool permitted_event_name(const char *name)
260+
{
261+
bool has_lower = false, has_upper = false;
262+
263+
for (size_t i = 0; i < strlen(name); i++) {
264+
char c = name[i];
265+
266+
if (islower(c)) {
267+
if (has_upper)
268+
return false;
269+
has_lower = true;
270+
continue;
271+
}
272+
if (isupper(c)) {
273+
if (has_lower)
274+
return false;
275+
has_upper = true;
276+
continue;
277+
}
278+
if (!isdigit(c) && c != '.' && c != '_' && c != '-')
279+
return false;
280+
}
281+
return true;
282+
}
283+
284+
static int test__pmu_event_names(struct test_suite *test __maybe_unused,
285+
int subtest __maybe_unused)
286+
{
287+
char path[PATH_MAX];
288+
DIR *pmu_dir, *event_dir;
289+
struct dirent *pmu_dent, *event_dent;
290+
const char *sysfs = sysfs__mountpoint();
291+
int ret = TEST_OK;
292+
293+
if (!sysfs) {
294+
pr_err("Sysfs not mounted\n");
295+
return TEST_FAIL;
296+
}
297+
298+
snprintf(path, sizeof(path), "%s/bus/event_source/devices/", sysfs);
299+
pmu_dir = opendir(path);
300+
if (!pmu_dir) {
301+
pr_err("Error opening \"%s\"\n", path);
302+
return TEST_FAIL;
303+
}
304+
while ((pmu_dent = readdir(pmu_dir))) {
305+
if (!strcmp(pmu_dent->d_name, ".") ||
306+
!strcmp(pmu_dent->d_name, ".."))
307+
continue;
308+
309+
snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/type",
310+
sysfs, pmu_dent->d_name);
311+
312+
/* Does it look like a PMU? */
313+
if (!file_available(path))
314+
continue;
315+
316+
/* Process events. */
317+
snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/events",
318+
sysfs, pmu_dent->d_name);
319+
320+
event_dir = opendir(path);
321+
if (!event_dir) {
322+
pr_debug("Skipping as no event directory \"%s\"\n", path);
323+
continue;
324+
}
325+
while ((event_dent = readdir(event_dir))) {
326+
const char *event_name = event_dent->d_name;
327+
328+
if (!strcmp(event_name, ".") || !strcmp(event_name, ".."))
329+
continue;
330+
331+
if (!permitted_event_name(event_name)) {
332+
pr_err("Invalid sysfs event name: %s/%s\n",
333+
pmu_dent->d_name, event_name);
334+
ret = TEST_FAIL;
335+
}
336+
}
337+
closedir(event_dir);
338+
}
339+
closedir(pmu_dir);
340+
return ret;
341+
}
342+
254343
static struct test_case tests__pmu[] = {
255344
TEST_CASE("Parsing with PMU format directory", pmu_format),
256345
TEST_CASE("Parsing with PMU event", pmu_events),
346+
TEST_CASE("PMU event names", pmu_event_names),
257347
{ .name = NULL, }
258348
};
259349

0 commit comments

Comments
 (0)