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_event(evlist, name); 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 *const 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_event(evlist, names[i]); 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 static int test__perf_evsel__roundtrip_name_test(struct test_suite *test __maybe_unused, 103 int subtest __maybe_unused) 104 { 105 int err = 0, ret = 0; 106 107 if (perf_pmu__has_hybrid() && perf_pmu__hybrid_mounted("cpu_atom")) 108 return perf_evsel__name_array_test(evsel__hw_names, 2); 109 110 err = perf_evsel__name_array_test(evsel__hw_names, 1); 111 if (err) 112 ret = err; 113 114 err = __perf_evsel__name_array_test(evsel__sw_names, PERF_COUNT_SW_DUMMY + 1, 1); 115 if (err) 116 ret = err; 117 118 err = perf_evsel__roundtrip_cache_name_test(); 119 if (err) 120 ret = err; 121 122 return ret; 123 } 124 125 DEFINE_SUITE("Roundtrip evsel->name", perf_evsel__roundtrip_name_test); 126