0001
0002 #include "evlist.h"
0003 #include "evsel.h"
0004 #include "parse-events.h"
0005 #include "tests.h"
0006 #include "debug.h"
0007 #include "pmu.h"
0008 #include "pmu-hybrid.h"
0009 #include <errno.h>
0010 #include <linux/kernel.h>
0011
0012 static int perf_evsel__roundtrip_cache_name_test(void)
0013 {
0014 char name[128];
0015 int type, op, err = 0, ret = 0, i, idx;
0016 struct evsel *evsel;
0017 struct evlist *evlist = evlist__new();
0018
0019 if (evlist == NULL)
0020 return -ENOMEM;
0021
0022 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
0023 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
0024
0025 if (!evsel__is_cache_op_valid(type, op))
0026 continue;
0027
0028 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
0029 __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name));
0030 err = parse_event(evlist, name);
0031 if (err)
0032 ret = err;
0033 }
0034 }
0035 }
0036
0037 idx = 0;
0038 evsel = evlist__first(evlist);
0039
0040 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
0041 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
0042
0043 if (!evsel__is_cache_op_valid(type, op))
0044 continue;
0045
0046 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
0047 __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name));
0048 if (evsel->core.idx != idx)
0049 continue;
0050
0051 ++idx;
0052
0053 if (strcmp(evsel__name(evsel), name)) {
0054 pr_debug("%s != %s\n", evsel__name(evsel), name);
0055 ret = -1;
0056 }
0057
0058 evsel = evsel__next(evsel);
0059 }
0060 }
0061 }
0062
0063 evlist__delete(evlist);
0064 return ret;
0065 }
0066
0067 static int __perf_evsel__name_array_test(const char *const names[], int nr_names,
0068 int distance)
0069 {
0070 int i, err;
0071 struct evsel *evsel;
0072 struct evlist *evlist = evlist__new();
0073
0074 if (evlist == NULL)
0075 return -ENOMEM;
0076
0077 for (i = 0; i < nr_names; ++i) {
0078 err = parse_event(evlist, names[i]);
0079 if (err) {
0080 pr_debug("failed to parse event '%s', err %d\n",
0081 names[i], err);
0082 goto out_delete_evlist;
0083 }
0084 }
0085
0086 err = 0;
0087 evlist__for_each_entry(evlist, evsel) {
0088 if (strcmp(evsel__name(evsel), names[evsel->core.idx / distance])) {
0089 --err;
0090 pr_debug("%s != %s\n", evsel__name(evsel), names[evsel->core.idx / distance]);
0091 }
0092 }
0093
0094 out_delete_evlist:
0095 evlist__delete(evlist);
0096 return err;
0097 }
0098
0099 #define perf_evsel__name_array_test(names, distance) \
0100 __perf_evsel__name_array_test(names, ARRAY_SIZE(names), distance)
0101
0102 static int test__perf_evsel__roundtrip_name_test(struct test_suite *test __maybe_unused,
0103 int subtest __maybe_unused)
0104 {
0105 int err = 0, ret = 0;
0106
0107 if (perf_pmu__has_hybrid() && perf_pmu__hybrid_mounted("cpu_atom"))
0108 return perf_evsel__name_array_test(evsel__hw_names, 2);
0109
0110 err = perf_evsel__name_array_test(evsel__hw_names, 1);
0111 if (err)
0112 ret = err;
0113
0114 err = __perf_evsel__name_array_test(evsel__sw_names, PERF_COUNT_SW_DUMMY + 1, 1);
0115 if (err)
0116 ret = err;
0117
0118 err = perf_evsel__roundtrip_cache_name_test();
0119 if (err)
0120 ret = err;
0121
0122 return ret;
0123 }
0124
0125 DEFINE_SUITE("Roundtrip evsel->name", perf_evsel__roundtrip_name_test);