xref: /linux/tools/perf/tests/pmu.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1 // SPDX-License-Identifier: GPL-2.0
2 #include "evlist.h"
3 #include "evsel.h"
4 #include "parse-events.h"
5 #include "pmu.h"
6 #include "pmus.h"
7 #include "tests.h"
8 #include "debug.h"
9 #include "fncache.h"
10 #include <api/fs/fs.h>
11 #include <ctype.h>
12 #include <dirent.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 
21 /* Cleanup test PMU directory. */
22 static int test_pmu_put(const char *dir, struct perf_pmu *pmu)
23 {
24 	char buf[PATH_MAX + 20];
25 	int ret;
26 
27 	if (scnprintf(buf, sizeof(buf), "rm -fr %s", dir) < 0) {
28 		pr_err("Failure to set up buffer for \"%s\"\n", dir);
29 		return -EINVAL;
30 	}
31 	ret = system(buf);
32 	if (ret)
33 		pr_err("Failure to \"%s\"\n", buf);
34 
35 	list_del(&pmu->list);
36 	perf_pmu__delete(pmu);
37 	return ret;
38 }
39 
40 /*
41  * Prepare test PMU directory data, normally exported by kernel at
42  * /sys/bus/event_source/devices/<pmu>/. Give as input a buffer to hold the file
43  * path, the result is PMU loaded using that directory.
44  */
45 static struct perf_pmu *test_pmu_get(char *dir, size_t sz)
46 {
47 	/* Simulated format definitions. */
48 	const struct test_format {
49 		const char *name;
50 		const char *value;
51 	} test_formats[] = {
52 		{ "krava01", "config:0-1,62-63\n", },
53 		{ "krava02", "config:10-17\n", },
54 		{ "krava03", "config:5\n", },
55 		{ "krava11", "config1:0,2,4,6,8,20-28\n", },
56 		{ "krava12", "config1:63\n", },
57 		{ "krava13", "config1:45-47\n", },
58 		{ "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", },
59 		{ "krava22", "config2:8,18,48,58\n", },
60 		{ "krava23", "config2:28-29,38\n", },
61 	};
62 	const char *test_event = "krava01=15,krava02=170,krava03=1,krava11=27,krava12=1,"
63 		"krava13=2,krava21=119,krava22=11,krava23=2\n";
64 
65 	char name[PATH_MAX];
66 	int dirfd, file;
67 	struct perf_pmu *pmu = NULL;
68 	ssize_t len;
69 
70 	/* Create equivalent of sysfs mount point. */
71 	scnprintf(dir, sz, "/tmp/perf-pmu-test-XXXXXX");
72 	if (!mkdtemp(dir)) {
73 		pr_err("mkdtemp failed\n");
74 		dir[0] = '\0';
75 		return NULL;
76 	}
77 	dirfd = open(dir, O_DIRECTORY);
78 	if (dirfd < 0) {
79 		pr_err("Failed to open test directory \"%s\"\n", dir);
80 		goto err_out;
81 	}
82 
83 	/* Create the test PMU directory and give it a perf_event_attr type number. */
84 	if (mkdirat(dirfd, "perf-pmu-test", 0755) < 0) {
85 		pr_err("Failed to mkdir PMU directory\n");
86 		goto err_out;
87 	}
88 	file = openat(dirfd, "perf-pmu-test/type", O_WRONLY | O_CREAT, 0600);
89 	if (!file) {
90 		pr_err("Failed to open for writing file \"type\"\n");
91 		goto err_out;
92 	}
93 	len = strlen("9999");
94 	if (write(file, "9999\n", len) < len) {
95 		close(file);
96 		pr_err("Failed to write to 'type' file\n");
97 		goto err_out;
98 	}
99 	close(file);
100 
101 	/* Create format directory and files. */
102 	if (mkdirat(dirfd, "perf-pmu-test/format", 0755) < 0) {
103 		pr_err("Failed to mkdir PMU format directory\n)");
104 		goto err_out;
105 	}
106 	for (size_t i = 0; i < ARRAY_SIZE(test_formats); i++) {
107 		const struct test_format *format = &test_formats[i];
108 
109 		if (scnprintf(name, PATH_MAX, "perf-pmu-test/format/%s", format->name) < 0) {
110 			pr_err("Failure to set up path for \"%s\"\n", format->name);
111 			goto err_out;
112 		}
113 		file = openat(dirfd, name, O_WRONLY | O_CREAT, 0600);
114 		if (!file) {
115 			pr_err("Failed to open for writing file \"%s\"\n", name);
116 			goto err_out;
117 		}
118 
119 		if (write(file, format->value, strlen(format->value)) < 0) {
120 			pr_err("Failed to write to file \"%s\"\n", name);
121 			close(file);
122 			goto err_out;
123 		}
124 		close(file);
125 	}
126 
127 	/* Create test event. */
128 	if (mkdirat(dirfd, "perf-pmu-test/events", 0755) < 0) {
129 		pr_err("Failed to mkdir PMU events directory\n");
130 		goto err_out;
131 	}
132 	file = openat(dirfd, "perf-pmu-test/events/test-event", O_WRONLY | O_CREAT, 0600);
133 	if (!file) {
134 		pr_err("Failed to open for writing file \"type\"\n");
135 		goto err_out;
136 	}
137 	len = strlen(test_event);
138 	if (write(file, test_event, len) < len) {
139 		close(file);
140 		pr_err("Failed to write to 'test-event' file\n");
141 		goto err_out;
142 	}
143 	close(file);
144 
145 	/* Make the PMU reading the files created above. */
146 	pmu = perf_pmus__add_test_pmu(dirfd, "perf-pmu-test");
147 	if (!pmu)
148 		pr_err("Test PMU creation failed\n");
149 
150 err_out:
151 	if (!pmu)
152 		test_pmu_put(dir, pmu);
153 	if (dirfd >= 0)
154 		close(dirfd);
155 	return pmu;
156 }
157 
158 static int test__pmu_format(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
159 {
160 	char dir[PATH_MAX];
161 	struct perf_event_attr attr;
162 	struct parse_events_terms terms;
163 	int ret = TEST_FAIL;
164 	struct perf_pmu *pmu = test_pmu_get(dir, sizeof(dir));
165 
166 	if (!pmu)
167 		return TEST_FAIL;
168 
169 	parse_events_terms__init(&terms);
170 	if (parse_events_terms(&terms,
171 				"krava01=15,krava02=170,krava03=1,krava11=27,krava12=1,"
172 				"krava13=2,krava21=119,krava22=11,krava23=2")) {
173 		pr_err("Term parsing failed\n");
174 		goto err_out;
175 	}
176 
177 	memset(&attr, 0, sizeof(attr));
178 	ret = perf_pmu__config_terms(pmu, &attr, &terms, /*zero=*/false,
179 				     /*apply_hardcoded=*/false, /*err=*/NULL);
180 	if (ret) {
181 		pr_err("perf_pmu__config_terms failed");
182 		goto err_out;
183 	}
184 
185 	if (attr.config  != 0xc00000000002a823) {
186 		pr_err("Unexpected config value %llx\n", attr.config);
187 		goto err_out;
188 	}
189 	if (attr.config1 != 0x8000400000000145) {
190 		pr_err("Unexpected config1 value %llx\n", attr.config1);
191 		goto err_out;
192 	}
193 	if (attr.config2 != 0x0400000020041d07) {
194 		pr_err("Unexpected config2 value %llx\n", attr.config2);
195 	}
196 
197 	ret = TEST_OK;
198 err_out:
199 	parse_events_terms__exit(&terms);
200 	test_pmu_put(dir, pmu);
201 	return ret;
202 }
203 
204 static int test__pmu_usr_chgs(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
205 {
206 	const char *event = "perf-pmu-test/config=15,config1=4,krava02=170,"
207 			    "krava03=1,krava11=27,krava12=1/";
208 	struct parse_events_terms terms;
209 	struct parse_events_error err;
210 	LIST_HEAD(config_terms);
211 	struct evlist *evlist;
212 	struct perf_pmu *pmu;
213 	struct evsel *evsel;
214 	int ret = TEST_FAIL;
215 	char dir[PATH_MAX];
216 	u64 val;
217 
218 	pmu = test_pmu_get(dir, sizeof(dir));
219 	if (!pmu)
220 		return TEST_FAIL;
221 
222 	evlist = evlist__new();
223 	if (evlist == NULL) {
224 		pr_err("Failed allocation");
225 		goto err_out;
226 	}
227 
228 	parse_events_terms__init(&terms);
229 	ret = parse_events(evlist, event, &err);
230 	if (ret) {
231 		pr_debug("failed to parse event '%s', err %d\n", event, ret);
232 		parse_events_error__print(&err, event);
233 		if (parse_events_error__contains(&err, "can't access trace events"))
234 			ret = TEST_SKIP;
235 		goto err_out;
236 	}
237 	evsel = evlist__first(evlist);
238 
239 	/*
240 	 * Set via config=15, krava01 bits 0-1
241 	 * Set via config1=4, krava11 bit 1
242 	 * Set values: krava02=170, krava03=1, krava11=27, krava12=1
243 	 *
244 	 * Test that already set values aren't overwritten.
245 	 */
246 	evsel__set_config_if_unset(evsel, "krava01", 16);
247 	evsel__get_config_val(evsel, "krava01", &val);
248 	TEST_ASSERT_EQUAL("krava01 overwritten", (int) val, (15 & 0b11));
249 
250 	evsel__set_config_if_unset(evsel, "krava11", 45);
251 	evsel__get_config_val(evsel, "krava11", &val);
252 	TEST_ASSERT_EQUAL("krava11 overwritten", (int) val, (27 | (4 << 1)));
253 
254 	evsel__set_config_if_unset(evsel, "krava02", 32);
255 	evsel__get_config_val(evsel, "krava02", &val);
256 	TEST_ASSERT_EQUAL("krava02 overwritten", (int) val, 170);
257 
258 	evsel__set_config_if_unset(evsel, "krava03", 0);
259 	evsel__get_config_val(evsel, "krava03", &val);
260 	TEST_ASSERT_EQUAL("krava03 overwritten", (int) val, 1);
261 
262 	/*
263 	 * krava13 doesn't have any bits set by either krava13= or config1=
264 	 * but setting _any_ raw value for config1 implies that krava13
265 	 * shouldn't be overwritten. So it's value should remain as 0.
266 	 */
267 	evsel__set_config_if_unset(evsel, "krava13", 5);
268 	evsel__get_config_val(evsel, "krava13", &val);
269 	TEST_ASSERT_EQUAL("krava13 overwritten", (int) val, 0);
270 
271 	/*
272 	 * Unset values: krava21, krava22, krava23
273 	 *
274 	 * Test that unset values are overwritten.
275 	 */
276 	evsel__set_config_if_unset(evsel, "krava21", 13905);
277 	evsel__get_config_val(evsel, "krava21", &val);
278 	TEST_ASSERT_EQUAL("krava21 not overwritten", (int) val, 13905);
279 
280 	evsel__set_config_if_unset(evsel, "krava22", 11);
281 	evsel__get_config_val(evsel, "krava22", &val);
282 	TEST_ASSERT_EQUAL("krava22 not overwritten", (int) val, 11);
283 
284 	evsel__set_config_if_unset(evsel, "krava23", 0);
285 	evsel__get_config_val(evsel, "krava23", &val);
286 	TEST_ASSERT_EQUAL("krava23 not overwritten", (int) val, 0);
287 	ret = TEST_OK;
288 err_out:
289 	parse_events_terms__exit(&terms);
290 	evlist__delete(evlist);
291 	test_pmu_put(dir, pmu);
292 	return ret;
293 }
294 
295 static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
296 {
297 	char dir[PATH_MAX];
298 	struct parse_events_error err;
299 	struct evlist *evlist;
300 	struct evsel *evsel;
301 	struct perf_event_attr *attr;
302 	int ret = TEST_FAIL;
303 	struct perf_pmu *pmu = test_pmu_get(dir, sizeof(dir));
304 	const char *event = "perf-pmu-test/test-event/";
305 
306 
307 	if (!pmu)
308 		return TEST_FAIL;
309 
310 	evlist = evlist__new();
311 	if (evlist == NULL) {
312 		pr_err("Failed allocation");
313 		goto err_out;
314 	}
315 	parse_events_error__init(&err);
316 	ret = parse_events(evlist, event, &err);
317 	if (ret) {
318 		pr_debug("failed to parse event '%s', err %d\n", event, ret);
319 		parse_events_error__print(&err, event);
320 		if (parse_events_error__contains(&err, "can't access trace events"))
321 			ret = TEST_SKIP;
322 		goto err_out;
323 	}
324 	evsel = evlist__first(evlist);
325 	attr = &evsel->core.attr;
326 	if (attr->config  != 0xc00000000002a823) {
327 		pr_err("Unexpected config value %llx\n", attr->config);
328 		goto err_out;
329 	}
330 	if (attr->config1 != 0x8000400000000145) {
331 		pr_err("Unexpected config1 value %llx\n", attr->config1);
332 		goto err_out;
333 	}
334 	if (attr->config2 != 0x0400000020041d07) {
335 		pr_err("Unexpected config2 value %llx\n", attr->config2);
336 		goto err_out;
337 	}
338 
339 	ret = TEST_OK;
340 err_out:
341 	parse_events_error__exit(&err);
342 	evlist__delete(evlist);
343 	test_pmu_put(dir, pmu);
344 	return ret;
345 }
346 
347 static bool permitted_event_name(const char *name)
348 {
349 	bool has_lower = false, has_upper = false;
350 	__u64 config;
351 
352 	for (size_t i = 0; i < strlen(name); i++) {
353 		char c = name[i];
354 
355 		if (islower(c)) {
356 			if (has_upper)
357 				goto check_legacy;
358 			has_lower = true;
359 			continue;
360 		}
361 		if (isupper(c)) {
362 			if (has_lower)
363 				goto check_legacy;
364 			has_upper = true;
365 			continue;
366 		}
367 		if (!isdigit(c) && c != '.' && c != '_' && c != '-')
368 			goto check_legacy;
369 	}
370 	return true;
371 check_legacy:
372 	/*
373 	 * If the event name matches a legacy cache name the legacy encoding
374 	 * will still be used. This isn't quite WAI as sysfs events should take
375 	 * priority, but this case happens on PowerPC and matches the behavior
376 	 * in older perf tools where legacy events were the priority. Be
377 	 * permissive and assume later PMU drivers will use all lower or upper
378 	 * case names.
379 	 */
380 	if (parse_events__decode_legacy_cache(name, /*extended_pmu_type=*/0, &config) == 0) {
381 		pr_warning("sysfs event '%s' should be all lower/upper case, it will be matched using legacy encoding.",
382 			   name);
383 		return true;
384 	}
385 	return false;
386 }
387 
388 static int test__pmu_event_names(struct test_suite *test __maybe_unused,
389 				 int subtest __maybe_unused)
390 {
391 	char path[PATH_MAX];
392 	DIR *pmu_dir, *event_dir;
393 	struct dirent *pmu_dent, *event_dent;
394 	const char *sysfs = sysfs__mountpoint();
395 	int ret = TEST_OK;
396 
397 	if (!sysfs) {
398 		pr_err("Sysfs not mounted\n");
399 		return TEST_FAIL;
400 	}
401 
402 	snprintf(path, sizeof(path), "%s/bus/event_source/devices/", sysfs);
403 	pmu_dir = opendir(path);
404 	if (!pmu_dir) {
405 		pr_err("Error opening \"%s\"\n", path);
406 		return TEST_FAIL;
407 	}
408 	while ((pmu_dent = readdir(pmu_dir))) {
409 		if (!strcmp(pmu_dent->d_name, ".") ||
410 		    !strcmp(pmu_dent->d_name, ".."))
411 			continue;
412 
413 		snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/type",
414 			 sysfs, pmu_dent->d_name);
415 
416 		/* Does it look like a PMU? */
417 		if (!file_available(path))
418 			continue;
419 
420 		/* Process events. */
421 		snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/events",
422 			 sysfs, pmu_dent->d_name);
423 
424 		event_dir = opendir(path);
425 		if (!event_dir) {
426 			pr_debug("Skipping as no event directory \"%s\"\n", path);
427 			continue;
428 		}
429 		while ((event_dent = readdir(event_dir))) {
430 			const char *event_name = event_dent->d_name;
431 
432 			if (!strcmp(event_name, ".") || !strcmp(event_name, ".."))
433 				continue;
434 
435 			if (!permitted_event_name(event_name)) {
436 				pr_err("Invalid sysfs event name: %s/%s\n",
437 					pmu_dent->d_name, event_name);
438 				ret = TEST_FAIL;
439 			}
440 		}
441 		closedir(event_dir);
442 	}
443 	closedir(pmu_dir);
444 	return ret;
445 }
446 
447 static const char * const uncore_chas[] = {
448 	"uncore_cha_0",
449 	"uncore_cha_1",
450 	"uncore_cha_2",
451 	"uncore_cha_3",
452 	"uncore_cha_4",
453 	"uncore_cha_5",
454 	"uncore_cha_6",
455 	"uncore_cha_7",
456 	"uncore_cha_8",
457 	"uncore_cha_9",
458 	"uncore_cha_10",
459 	"uncore_cha_11",
460 	"uncore_cha_12",
461 	"uncore_cha_13",
462 	"uncore_cha_14",
463 	"uncore_cha_15",
464 	"uncore_cha_16",
465 	"uncore_cha_17",
466 	"uncore_cha_18",
467 	"uncore_cha_19",
468 	"uncore_cha_20",
469 	"uncore_cha_21",
470 	"uncore_cha_22",
471 	"uncore_cha_23",
472 	"uncore_cha_24",
473 	"uncore_cha_25",
474 	"uncore_cha_26",
475 	"uncore_cha_27",
476 	"uncore_cha_28",
477 	"uncore_cha_29",
478 	"uncore_cha_30",
479 	"uncore_cha_31",
480 };
481 
482 static const char * const mrvl_ddrs[] = {
483 	"mrvl_ddr_pmu_87e1b0000000",
484 	"mrvl_ddr_pmu_87e1b1000000",
485 	"mrvl_ddr_pmu_87e1b2000000",
486 	"mrvl_ddr_pmu_87e1b3000000",
487 	"mrvl_ddr_pmu_87e1b4000000",
488 	"mrvl_ddr_pmu_87e1b5000000",
489 	"mrvl_ddr_pmu_87e1b6000000",
490 	"mrvl_ddr_pmu_87e1b7000000",
491 	"mrvl_ddr_pmu_87e1b8000000",
492 	"mrvl_ddr_pmu_87e1b9000000",
493 	"mrvl_ddr_pmu_87e1ba000000",
494 	"mrvl_ddr_pmu_87e1bb000000",
495 	"mrvl_ddr_pmu_87e1bc000000",
496 	"mrvl_ddr_pmu_87e1bd000000",
497 	"mrvl_ddr_pmu_87e1be000000",
498 	"mrvl_ddr_pmu_87e1bf000000",
499 };
500 
501 static int test__name_len(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
502 {
503 	TEST_ASSERT_VAL("cpu", pmu_name_len_no_suffix("cpu") == strlen("cpu"));
504 	TEST_ASSERT_VAL("i915", pmu_name_len_no_suffix("i915") == strlen("i915"));
505 	TEST_ASSERT_VAL("cpum_cf", pmu_name_len_no_suffix("cpum_cf") == strlen("cpum_cf"));
506 	for (size_t i = 0; i < ARRAY_SIZE(uncore_chas); i++) {
507 		TEST_ASSERT_VAL("Strips uncore_cha suffix",
508 				pmu_name_len_no_suffix(uncore_chas[i]) ==
509 				strlen("uncore_cha"));
510 	}
511 	for (size_t i = 0; i < ARRAY_SIZE(mrvl_ddrs); i++) {
512 		TEST_ASSERT_VAL("Strips mrvl_ddr_pmu suffix",
513 				pmu_name_len_no_suffix(mrvl_ddrs[i]) ==
514 				strlen("mrvl_ddr_pmu"));
515 	}
516 	return TEST_OK;
517 }
518 
519 static int test__name_cmp(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
520 {
521 	TEST_ASSERT_EQUAL("cpu", pmu_name_cmp("cpu", "cpu"), 0);
522 	TEST_ASSERT_EQUAL("i915", pmu_name_cmp("i915", "i915"), 0);
523 	TEST_ASSERT_EQUAL("cpum_cf", pmu_name_cmp("cpum_cf", "cpum_cf"), 0);
524 	TEST_ASSERT_VAL("i915", pmu_name_cmp("cpu", "i915") < 0);
525 	TEST_ASSERT_VAL("i915", pmu_name_cmp("i915", "cpu") > 0);
526 	TEST_ASSERT_VAL("cpum_cf", pmu_name_cmp("cpum_cf", "cpum_ce") > 0);
527 	TEST_ASSERT_VAL("cpum_cf", pmu_name_cmp("cpum_cf", "cpum_d0") < 0);
528 	for (size_t i = 1; i < ARRAY_SIZE(uncore_chas); i++) {
529 		TEST_ASSERT_VAL("uncore_cha suffixes ordered lt",
530 				pmu_name_cmp(uncore_chas[i-1], uncore_chas[i]) < 0);
531 		TEST_ASSERT_VAL("uncore_cha suffixes ordered gt",
532 				pmu_name_cmp(uncore_chas[i], uncore_chas[i-1]) > 0);
533 	}
534 	for (size_t i = 1; i < ARRAY_SIZE(mrvl_ddrs); i++) {
535 		TEST_ASSERT_VAL("mrvl_ddr_pmu suffixes ordered lt",
536 				pmu_name_cmp(mrvl_ddrs[i-1], mrvl_ddrs[i]) < 0);
537 		TEST_ASSERT_VAL("mrvl_ddr_pmu suffixes ordered gt",
538 				pmu_name_cmp(mrvl_ddrs[i], mrvl_ddrs[i-1]) > 0);
539 	}
540 	return TEST_OK;
541 }
542 
543 /**
544  * Test perf_pmu__wildcard_match() that's used to search for a PMU given a name passed
545  * on the command line. The name that's passed may also be a filename type glob
546  * match. If the name does not match, perf_pmu__wildcard_match() attempts to match the
547  * alias of the PMU, if provided.
548  */
549 static int test__pmu_match(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
550 {
551 	struct perf_pmu test_pmu = {
552 		.name = "pmuname",
553 	};
554 
555 #define TEST_PMU_MATCH(msg, to_match, expect)				\
556 	TEST_ASSERT_EQUAL(msg, perf_pmu__wildcard_match(&test_pmu, to_match), expect)
557 
558 	TEST_PMU_MATCH("Exact match", "pmuname", true);
559 	TEST_PMU_MATCH("Longer token", "longertoken", false);
560 	TEST_PMU_MATCH("Shorter token", "pmu", false);
561 
562 	test_pmu.name = "pmuname_10";
563 	TEST_PMU_MATCH("Diff suffix_", "pmuname_2", false);
564 	TEST_PMU_MATCH("Sub suffix_", "pmuname_1", true);
565 	TEST_PMU_MATCH("Same suffix_", "pmuname_10", true);
566 	TEST_PMU_MATCH("No suffix_", "pmuname", true);
567 	TEST_PMU_MATCH("Underscore_", "pmuname_", true);
568 	TEST_PMU_MATCH("Substring_", "pmuna", false);
569 
570 	test_pmu.name = "pmuname_ab23";
571 	TEST_PMU_MATCH("Diff suffix hex_", "pmuname_2", false);
572 	TEST_PMU_MATCH("Sub suffix hex_", "pmuname_ab", true);
573 	TEST_PMU_MATCH("Same suffix hex_", "pmuname_ab23", true);
574 	TEST_PMU_MATCH("No suffix hex_", "pmuname", true);
575 	TEST_PMU_MATCH("Underscore hex_", "pmuname_", true);
576 	TEST_PMU_MATCH("Substring hex_", "pmuna", false);
577 
578 	test_pmu.name = "pmuname10";
579 	TEST_PMU_MATCH("Diff suffix", "pmuname2", false);
580 	TEST_PMU_MATCH("Sub suffix", "pmuname1", true);
581 	TEST_PMU_MATCH("Same suffix", "pmuname10", true);
582 	TEST_PMU_MATCH("No suffix", "pmuname", true);
583 	TEST_PMU_MATCH("Underscore", "pmuname_", false);
584 	TEST_PMU_MATCH("Substring", "pmuna", false);
585 
586 	test_pmu.name = "pmunameab23";
587 	TEST_PMU_MATCH("Diff suffix hex", "pmuname2", false);
588 	TEST_PMU_MATCH("Sub suffix hex", "pmunameab", true);
589 	TEST_PMU_MATCH("Same suffix hex", "pmunameab23", true);
590 	TEST_PMU_MATCH("No suffix hex", "pmuname", true);
591 	TEST_PMU_MATCH("Underscore hex", "pmuname_", false);
592 	TEST_PMU_MATCH("Substring hex",   "pmuna", false);
593 
594 	/*
595 	 * 2 hex chars or less are not considered suffixes so it shouldn't be
596 	 * possible to wildcard by skipping the suffix. Therefore there are more
597 	 * false results here than above.
598 	 */
599 	test_pmu.name = "pmuname_a3";
600 	TEST_PMU_MATCH("Diff suffix 2 hex_", "pmuname_2", false);
601 	/*
602 	 * This one should be false, but because pmuname_a3 ends in 3 which is
603 	 * decimal, it's not possible to determine if it's a short hex suffix or
604 	 * a normal decimal suffix following text. And we want to match on any
605 	 * length of decimal suffix. Run the test anyway and expect the wrong
606 	 * result. And slightly fuzzy matching shouldn't do too much harm.
607 	 */
608 	TEST_PMU_MATCH("Sub suffix 2 hex_", "pmuname_a", true);
609 	TEST_PMU_MATCH("Same suffix 2 hex_", "pmuname_a3", true);
610 	TEST_PMU_MATCH("No suffix 2 hex_", "pmuname", false);
611 	TEST_PMU_MATCH("Underscore 2 hex_", "pmuname_", false);
612 	TEST_PMU_MATCH("Substring 2 hex_", "pmuna", false);
613 
614 	test_pmu.name = "pmuname_5";
615 	TEST_PMU_MATCH("Glob 1", "pmu*", true);
616 	TEST_PMU_MATCH("Glob 2", "nomatch*", false);
617 	TEST_PMU_MATCH("Seq 1", "pmuname_[12345]", true);
618 	TEST_PMU_MATCH("Seq 2", "pmuname_[67890]", false);
619 	TEST_PMU_MATCH("? 1", "pmuname_?", true);
620 	TEST_PMU_MATCH("? 2", "pmuname_1?", false);
621 
622 	return TEST_OK;
623 }
624 
625 static struct test_case tests__pmu[] = {
626 	TEST_CASE("Parsing with PMU format directory", pmu_format),
627 	TEST_CASE("Parsing with PMU event", pmu_events),
628 	TEST_CASE("PMU event names", pmu_event_names),
629 	TEST_CASE("PMU name combining", name_len),
630 	TEST_CASE("PMU name comparison", name_cmp),
631 	TEST_CASE("PMU cmdline match", pmu_match),
632 	TEST_CASE("PMU user config changes", pmu_usr_chgs),
633 	{	.name = NULL, }
634 };
635 
636 struct test_suite suite__pmu = {
637 	.desc = "Sysfs PMU tests",
638 	.test_cases = tests__pmu,
639 };
640