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