]> Git Repo - J-linux.git/blob - tools/perf/tests/pmu.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / perf / tests / pmu.c
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                                 NULL)) {
174                 pr_err("Term parsing failed\n");
175                 goto err_out;
176         }
177
178         memset(&attr, 0, sizeof(attr));
179         ret = perf_pmu__config_terms(pmu, &attr, &terms, /*zero=*/false,
180                                      /*apply_hardcoded=*/false, /*err=*/NULL);
181         if (ret) {
182                 pr_err("perf_pmu__config_terms failed");
183                 goto err_out;
184         }
185
186         if (attr.config  != 0xc00000000002a823) {
187                 pr_err("Unexpected config value %llx\n", attr.config);
188                 goto err_out;
189         }
190         if (attr.config1 != 0x8000400000000145) {
191                 pr_err("Unexpected config1 value %llx\n", attr.config1);
192                 goto err_out;
193         }
194         if (attr.config2 != 0x0400000020041d07) {
195                 pr_err("Unexpected config2 value %llx\n", attr.config2);
196                 goto err_out;
197         }
198
199         ret = TEST_OK;
200 err_out:
201         parse_events_terms__exit(&terms);
202         test_pmu_put(dir, pmu);
203         return ret;
204 }
205
206 static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
207 {
208         char dir[PATH_MAX];
209         struct parse_events_error err;
210         struct evlist *evlist;
211         struct evsel *evsel;
212         struct perf_event_attr *attr;
213         int ret = TEST_FAIL;
214         struct perf_pmu *pmu = test_pmu_get(dir, sizeof(dir));
215         const char *event = "perf-pmu-test/test-event/";
216
217
218         if (!pmu)
219                 return TEST_FAIL;
220
221         evlist = evlist__new();
222         if (evlist == NULL) {
223                 pr_err("Failed allocation");
224                 goto err_out;
225         }
226         parse_events_error__init(&err);
227         ret = parse_events(evlist, event, &err);
228         if (ret) {
229                 pr_debug("failed to parse event '%s', err %d\n", event, ret);
230                 parse_events_error__print(&err, event);
231                 if (parse_events_error__contains(&err, "can't access trace events"))
232                         ret = TEST_SKIP;
233                 goto err_out;
234         }
235         evsel = evlist__first(evlist);
236         attr = &evsel->core.attr;
237         if (attr->config  != 0xc00000000002a823) {
238                 pr_err("Unexpected config value %llx\n", attr->config);
239                 goto err_out;
240         }
241         if (attr->config1 != 0x8000400000000145) {
242                 pr_err("Unexpected config1 value %llx\n", attr->config1);
243                 goto err_out;
244         }
245         if (attr->config2 != 0x0400000020041d07) {
246                 pr_err("Unexpected config2 value %llx\n", attr->config2);
247                 goto err_out;
248         }
249
250         ret = TEST_OK;
251 err_out:
252         parse_events_error__exit(&err);
253         evlist__delete(evlist);
254         test_pmu_put(dir, pmu);
255         return ret;
256 }
257
258 static bool permitted_event_name(const char *name)
259 {
260         bool has_lower = false, has_upper = false;
261         __u64 config;
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                                 goto check_legacy;
269                         has_lower = true;
270                         continue;
271                 }
272                 if (isupper(c)) {
273                         if (has_lower)
274                                 goto check_legacy;
275                         has_upper = true;
276                         continue;
277                 }
278                 if (!isdigit(c) && c != '.' && c != '_' && c != '-')
279                         goto check_legacy;
280         }
281         return true;
282 check_legacy:
283         /*
284          * If the event name matches a legacy cache name the legacy encoding
285          * will still be used. This isn't quite WAI as sysfs events should take
286          * priority, but this case happens on PowerPC and matches the behavior
287          * in older perf tools where legacy events were the priority. Be
288          * permissive and assume later PMU drivers will use all lower or upper
289          * case names.
290          */
291         if (parse_events__decode_legacy_cache(name, /*extended_pmu_type=*/0, &config) == 0) {
292                 pr_warning("sysfs event '%s' should be all lower/upper case, it will be matched using legacy encoding.",
293                            name);
294                 return true;
295         }
296         return false;
297 }
298
299 static int test__pmu_event_names(struct test_suite *test __maybe_unused,
300                                  int subtest __maybe_unused)
301 {
302         char path[PATH_MAX];
303         DIR *pmu_dir, *event_dir;
304         struct dirent *pmu_dent, *event_dent;
305         const char *sysfs = sysfs__mountpoint();
306         int ret = TEST_OK;
307
308         if (!sysfs) {
309                 pr_err("Sysfs not mounted\n");
310                 return TEST_FAIL;
311         }
312
313         snprintf(path, sizeof(path), "%s/bus/event_source/devices/", sysfs);
314         pmu_dir = opendir(path);
315         if (!pmu_dir) {
316                 pr_err("Error opening \"%s\"\n", path);
317                 return TEST_FAIL;
318         }
319         while ((pmu_dent = readdir(pmu_dir))) {
320                 if (!strcmp(pmu_dent->d_name, ".") ||
321                     !strcmp(pmu_dent->d_name, ".."))
322                         continue;
323
324                 snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/type",
325                          sysfs, pmu_dent->d_name);
326
327                 /* Does it look like a PMU? */
328                 if (!file_available(path))
329                         continue;
330
331                 /* Process events. */
332                 snprintf(path, sizeof(path), "%s/bus/event_source/devices/%s/events",
333                          sysfs, pmu_dent->d_name);
334
335                 event_dir = opendir(path);
336                 if (!event_dir) {
337                         pr_debug("Skipping as no event directory \"%s\"\n", path);
338                         continue;
339                 }
340                 while ((event_dent = readdir(event_dir))) {
341                         const char *event_name = event_dent->d_name;
342
343                         if (!strcmp(event_name, ".") || !strcmp(event_name, ".."))
344                                 continue;
345
346                         if (!permitted_event_name(event_name)) {
347                                 pr_err("Invalid sysfs event name: %s/%s\n",
348                                         pmu_dent->d_name, event_name);
349                                 ret = TEST_FAIL;
350                         }
351                 }
352                 closedir(event_dir);
353         }
354         closedir(pmu_dir);
355         return ret;
356 }
357
358 static const char * const uncore_chas[] = {
359         "uncore_cha_0",
360         "uncore_cha_1",
361         "uncore_cha_2",
362         "uncore_cha_3",
363         "uncore_cha_4",
364         "uncore_cha_5",
365         "uncore_cha_6",
366         "uncore_cha_7",
367         "uncore_cha_8",
368         "uncore_cha_9",
369         "uncore_cha_10",
370         "uncore_cha_11",
371         "uncore_cha_12",
372         "uncore_cha_13",
373         "uncore_cha_14",
374         "uncore_cha_15",
375         "uncore_cha_16",
376         "uncore_cha_17",
377         "uncore_cha_18",
378         "uncore_cha_19",
379         "uncore_cha_20",
380         "uncore_cha_21",
381         "uncore_cha_22",
382         "uncore_cha_23",
383         "uncore_cha_24",
384         "uncore_cha_25",
385         "uncore_cha_26",
386         "uncore_cha_27",
387         "uncore_cha_28",
388         "uncore_cha_29",
389         "uncore_cha_30",
390         "uncore_cha_31",
391 };
392
393 static const char * const mrvl_ddrs[] = {
394         "mrvl_ddr_pmu_87e1b0000000",
395         "mrvl_ddr_pmu_87e1b1000000",
396         "mrvl_ddr_pmu_87e1b2000000",
397         "mrvl_ddr_pmu_87e1b3000000",
398         "mrvl_ddr_pmu_87e1b4000000",
399         "mrvl_ddr_pmu_87e1b5000000",
400         "mrvl_ddr_pmu_87e1b6000000",
401         "mrvl_ddr_pmu_87e1b7000000",
402         "mrvl_ddr_pmu_87e1b8000000",
403         "mrvl_ddr_pmu_87e1b9000000",
404         "mrvl_ddr_pmu_87e1ba000000",
405         "mrvl_ddr_pmu_87e1bb000000",
406         "mrvl_ddr_pmu_87e1bc000000",
407         "mrvl_ddr_pmu_87e1bd000000",
408         "mrvl_ddr_pmu_87e1be000000",
409         "mrvl_ddr_pmu_87e1bf000000",
410 };
411
412 static int test__name_len(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
413 {
414         TEST_ASSERT_VAL("cpu", pmu_name_len_no_suffix("cpu") == strlen("cpu"));
415         TEST_ASSERT_VAL("i915", pmu_name_len_no_suffix("i915") == strlen("i915"));
416         TEST_ASSERT_VAL("cpum_cf", pmu_name_len_no_suffix("cpum_cf") == strlen("cpum_cf"));
417         for (size_t i = 0; i < ARRAY_SIZE(uncore_chas); i++) {
418                 TEST_ASSERT_VAL("Strips uncore_cha suffix",
419                                 pmu_name_len_no_suffix(uncore_chas[i]) ==
420                                 strlen("uncore_cha"));
421         }
422         for (size_t i = 0; i < ARRAY_SIZE(mrvl_ddrs); i++) {
423                 TEST_ASSERT_VAL("Strips mrvl_ddr_pmu suffix",
424                                 pmu_name_len_no_suffix(mrvl_ddrs[i]) ==
425                                 strlen("mrvl_ddr_pmu"));
426         }
427         return TEST_OK;
428 }
429
430 static int test__name_cmp(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
431 {
432         TEST_ASSERT_EQUAL("cpu", pmu_name_cmp("cpu", "cpu"), 0);
433         TEST_ASSERT_EQUAL("i915", pmu_name_cmp("i915", "i915"), 0);
434         TEST_ASSERT_EQUAL("cpum_cf", pmu_name_cmp("cpum_cf", "cpum_cf"), 0);
435         TEST_ASSERT_VAL("i915", pmu_name_cmp("cpu", "i915") < 0);
436         TEST_ASSERT_VAL("i915", pmu_name_cmp("i915", "cpu") > 0);
437         TEST_ASSERT_VAL("cpum_cf", pmu_name_cmp("cpum_cf", "cpum_ce") > 0);
438         TEST_ASSERT_VAL("cpum_cf", pmu_name_cmp("cpum_cf", "cpum_d0") < 0);
439         for (size_t i = 1; i < ARRAY_SIZE(uncore_chas); i++) {
440                 TEST_ASSERT_VAL("uncore_cha suffixes ordered lt",
441                                 pmu_name_cmp(uncore_chas[i-1], uncore_chas[i]) < 0);
442                 TEST_ASSERT_VAL("uncore_cha suffixes ordered gt",
443                                 pmu_name_cmp(uncore_chas[i], uncore_chas[i-1]) > 0);
444         }
445         for (size_t i = 1; i < ARRAY_SIZE(mrvl_ddrs); i++) {
446                 TEST_ASSERT_VAL("mrvl_ddr_pmu suffixes ordered lt",
447                                 pmu_name_cmp(mrvl_ddrs[i-1], mrvl_ddrs[i]) < 0);
448                 TEST_ASSERT_VAL("mrvl_ddr_pmu suffixes ordered gt",
449                                 pmu_name_cmp(mrvl_ddrs[i], mrvl_ddrs[i-1]) > 0);
450         }
451         return TEST_OK;
452 }
453
454 /**
455  * Test perf_pmu__match() that's used to search for a PMU given a name passed
456  * on the command line. The name that's passed may also be a filename type glob
457  * match. If the name does not match, perf_pmu__match() attempts to match the
458  * alias of the PMU, if provided.
459  */
460 static int test__pmu_match(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
461 {
462         struct perf_pmu test_pmu = {
463                 .name = "pmuname",
464         };
465
466         TEST_ASSERT_EQUAL("Exact match", perf_pmu__match(&test_pmu, "pmuname"),      true);
467         TEST_ASSERT_EQUAL("Longer token", perf_pmu__match(&test_pmu, "longertoken"), false);
468         TEST_ASSERT_EQUAL("Shorter token", perf_pmu__match(&test_pmu, "pmu"),        false);
469
470         test_pmu.name = "pmuname_10";
471         TEST_ASSERT_EQUAL("Diff suffix_", perf_pmu__match(&test_pmu, "pmuname_2"),  false);
472         TEST_ASSERT_EQUAL("Sub suffix_",  perf_pmu__match(&test_pmu, "pmuname_1"),  true);
473         TEST_ASSERT_EQUAL("Same suffix_", perf_pmu__match(&test_pmu, "pmuname_10"), true);
474         TEST_ASSERT_EQUAL("No suffix_",   perf_pmu__match(&test_pmu, "pmuname"),    true);
475         TEST_ASSERT_EQUAL("Underscore_",  perf_pmu__match(&test_pmu, "pmuname_"),   true);
476         TEST_ASSERT_EQUAL("Substring_",   perf_pmu__match(&test_pmu, "pmuna"),      false);
477
478         test_pmu.name = "pmuname_ab23";
479         TEST_ASSERT_EQUAL("Diff suffix hex_", perf_pmu__match(&test_pmu, "pmuname_2"),    false);
480         TEST_ASSERT_EQUAL("Sub suffix hex_",  perf_pmu__match(&test_pmu, "pmuname_ab"),   true);
481         TEST_ASSERT_EQUAL("Same suffix hex_", perf_pmu__match(&test_pmu, "pmuname_ab23"), true);
482         TEST_ASSERT_EQUAL("No suffix hex_",   perf_pmu__match(&test_pmu, "pmuname"),      true);
483         TEST_ASSERT_EQUAL("Underscore hex_",  perf_pmu__match(&test_pmu, "pmuname_"),     true);
484         TEST_ASSERT_EQUAL("Substring hex_",   perf_pmu__match(&test_pmu, "pmuna"),       false);
485
486         test_pmu.name = "pmuname10";
487         TEST_ASSERT_EQUAL("Diff suffix", perf_pmu__match(&test_pmu, "pmuname2"),  false);
488         TEST_ASSERT_EQUAL("Sub suffix",  perf_pmu__match(&test_pmu, "pmuname1"),  true);
489         TEST_ASSERT_EQUAL("Same suffix", perf_pmu__match(&test_pmu, "pmuname10"), true);
490         TEST_ASSERT_EQUAL("No suffix",   perf_pmu__match(&test_pmu, "pmuname"),   true);
491         TEST_ASSERT_EQUAL("Underscore",  perf_pmu__match(&test_pmu, "pmuname_"),  false);
492         TEST_ASSERT_EQUAL("Substring",   perf_pmu__match(&test_pmu, "pmuna"),     false);
493
494         test_pmu.name = "pmunameab23";
495         TEST_ASSERT_EQUAL("Diff suffix hex", perf_pmu__match(&test_pmu, "pmuname2"),    false);
496         TEST_ASSERT_EQUAL("Sub suffix hex",  perf_pmu__match(&test_pmu, "pmunameab"),   true);
497         TEST_ASSERT_EQUAL("Same suffix hex", perf_pmu__match(&test_pmu, "pmunameab23"), true);
498         TEST_ASSERT_EQUAL("No suffix hex",   perf_pmu__match(&test_pmu, "pmuname"),     true);
499         TEST_ASSERT_EQUAL("Underscore hex",  perf_pmu__match(&test_pmu, "pmuname_"),    false);
500         TEST_ASSERT_EQUAL("Substring hex",   perf_pmu__match(&test_pmu, "pmuna"),       false);
501
502         /*
503          * 2 hex chars or less are not considered suffixes so it shouldn't be
504          * possible to wildcard by skipping the suffix. Therefore there are more
505          * false results here than above.
506          */
507         test_pmu.name = "pmuname_a3";
508         TEST_ASSERT_EQUAL("Diff suffix 2 hex_", perf_pmu__match(&test_pmu, "pmuname_2"),  false);
509         /*
510          * This one should be false, but because pmuname_a3 ends in 3 which is
511          * decimal, it's not possible to determine if it's a short hex suffix or
512          * a normal decimal suffix following text. And we want to match on any
513          * length of decimal suffix. Run the test anyway and expect the wrong
514          * result. And slightly fuzzy matching shouldn't do too much harm.
515          */
516         TEST_ASSERT_EQUAL("Sub suffix 2 hex_",  perf_pmu__match(&test_pmu, "pmuname_a"),  true);
517         TEST_ASSERT_EQUAL("Same suffix 2 hex_", perf_pmu__match(&test_pmu, "pmuname_a3"), true);
518         TEST_ASSERT_EQUAL("No suffix 2 hex_",   perf_pmu__match(&test_pmu, "pmuname"),    false);
519         TEST_ASSERT_EQUAL("Underscore 2 hex_",  perf_pmu__match(&test_pmu, "pmuname_"),   false);
520         TEST_ASSERT_EQUAL("Substring 2 hex_",   perf_pmu__match(&test_pmu, "pmuna"),      false);
521
522         test_pmu.name = "pmuname_5";
523         TEST_ASSERT_EQUAL("Glob 1", perf_pmu__match(&test_pmu, "pmu*"),            true);
524         TEST_ASSERT_EQUAL("Glob 2", perf_pmu__match(&test_pmu, "nomatch*"),        false);
525         TEST_ASSERT_EQUAL("Seq 1",  perf_pmu__match(&test_pmu, "pmuname_[12345]"), true);
526         TEST_ASSERT_EQUAL("Seq 2",  perf_pmu__match(&test_pmu, "pmuname_[67890]"), false);
527         TEST_ASSERT_EQUAL("? 1",    perf_pmu__match(&test_pmu, "pmuname_?"),       true);
528         TEST_ASSERT_EQUAL("? 2",    perf_pmu__match(&test_pmu, "pmuname_1?"),      false);
529
530         return TEST_OK;
531 }
532
533 static struct test_case tests__pmu[] = {
534         TEST_CASE("Parsing with PMU format directory", pmu_format),
535         TEST_CASE("Parsing with PMU event", pmu_events),
536         TEST_CASE("PMU event names", pmu_event_names),
537         TEST_CASE("PMU name combining", name_len),
538         TEST_CASE("PMU name comparison", name_cmp),
539         TEST_CASE("PMU cmdline match", pmu_match),
540         {       .name = NULL, }
541 };
542
543 struct test_suite suite__pmu = {
544         .desc = "Sysfs PMU tests",
545         .test_cases = tests__pmu,
546 };
This page took 0.061099 seconds and 4 git commands to generate.