1 // SPDX-License-Identifier: GPL-2.0 2 #include "evlist.h" 3 #include "evsel.h" 4 #include "parse-events.h" 5 #include "tests.h" 6 #include "debug.h" 7 #include "pmu.h" 8 #include <errno.h> 9 #include <linux/kernel.h> 10 11 static int perf_evsel__roundtrip_cache_name_test(void) 12 { 13 char name[128]; 14 int type, op, err = 0, ret = 0, i, idx; 15 struct evsel *evsel; 16 struct evlist *evlist = evlist__new(); 17 18 if (evlist == NULL) 19 return -ENOMEM; 20 21 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 22 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 23 /* skip invalid cache type */ 24 if (!evsel__is_cache_op_valid(type, op)) 25 continue; 26 27 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 28 __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); 29 err = parse_events(evlist, name, NULL); 30 if (err) 31 ret = err; 32 } 33 } 34 } 35 36 idx = 0; 37 evsel = evlist__first(evlist); 38 39 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 40 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 41 /* skip invalid cache type */ 42 if (!evsel__is_cache_op_valid(type, op)) 43 continue; 44 45 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 46 __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); 47 if (evsel->idx != idx) 48 continue; 49 50 ++idx; 51 52 if (strcmp(evsel__name(evsel), name)) { 53 pr_debug("%s != %s\n", evsel__name(evsel), name); 54 ret = -1; 55 } 56 57 evsel = evsel__next(evsel); 58 } 59 } 60 } 61 62 evlist__delete(evlist); 63 return ret; 64 } 65 66 static int __perf_evsel__name_array_test(const char *names[], int nr_names, 67 int distance) 68 { 69 int i, err; 70 struct evsel *evsel; 71 struct evlist *evlist = evlist__new(); 72 73 if (evlist == NULL) 74 return -ENOMEM; 75 76 for (i = 0; i < nr_names; ++i) { 77 err = parse_events(evlist, names[i], NULL); 78 if (err) { 79 pr_debug("failed to parse event '%s', err %d\n", 80 names[i], err); 81 goto out_delete_evlist; 82 } 83 } 84 85 err = 0; 86 evlist__for_each_entry(evlist, evsel) { 87 if (strcmp(evsel__name(evsel), names[evsel->idx / distance])) { 88 --err; 89 pr_debug("%s != %s\n", evsel__name(evsel), names[evsel->idx / distance]); 90 } 91 } 92 93 out_delete_evlist: 94 evlist__delete(evlist); 95 return err; 96 } 97 98 #define perf_evsel__name_array_test(names, distance) \ 99 __perf_evsel__name_array_test(names, ARRAY_SIZE(names), distance) 100 101 int test__perf_evsel__roundtrip_name_test(struct test *test __maybe_unused, int subtest __maybe_unused) 102 { 103 int err = 0, ret = 0; 104 105 if (perf_pmu__has_hybrid()) 106 return perf_evsel__name_array_test(evsel__hw_names, 2); 107 108 err = perf_evsel__name_array_test(evsel__hw_names, 1); 109 if (err) 110 ret = err; 111 112 err = __perf_evsel__name_array_test(evsel__sw_names, PERF_COUNT_SW_DUMMY + 1, 1); 113 if (err) 114 ret = err; 115 116 err = perf_evsel__roundtrip_cache_name_test(); 117 if (err) 118 ret = err; 119 120 return ret; 121 } 122