Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include "tests.h" |
| 3 | #include "debug.h" |
| 4 | #include "evlist.h" |
| 5 | #include "cgroup.h" |
| 6 | #include "rblist.h" |
| 7 | #include "metricgroup.h" |
| 8 | #include "parse-events.h" |
| 9 | #include "pmu-events/pmu-events.h" |
| 10 | #include "pfm.h" |
| 11 | #include <subcmd/parse-options.h> |
| 12 | #include <stdio.h> |
| 13 | #include <stdlib.h> |
| 14 | #include <string.h> |
| 15 | |
| 16 | static int test_expand_events(struct evlist *evlist, |
| 17 | struct rblist *metric_events) |
| 18 | { |
| 19 | int i, ret = TEST_FAIL; |
| 20 | int nr_events; |
| 21 | bool was_group_event; |
| 22 | int nr_members; /* for the first evsel only */ |
| 23 | const char cgrp_str[] = "A,B,C"; |
| 24 | const char *cgrp_name[] = { "A", "B", "C" }; |
| 25 | int nr_cgrps = ARRAY_SIZE(cgrp_name); |
| 26 | char **ev_name; |
| 27 | struct evsel *evsel; |
| 28 | |
Arnaldo Carvalho de Melo | e414fd1 | 2020-11-30 14:52:44 -0300 | [diff] [blame] | 29 | TEST_ASSERT_VAL("evlist is empty", !evlist__empty(evlist)); |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 30 | |
| 31 | nr_events = evlist->core.nr_entries; |
| 32 | ev_name = calloc(nr_events, sizeof(*ev_name)); |
| 33 | if (ev_name == NULL) { |
| 34 | pr_debug("memory allocation failure\n"); |
| 35 | return TEST_FAIL; |
| 36 | } |
| 37 | i = 0; |
| 38 | evlist__for_each_entry(evlist, evsel) { |
| 39 | ev_name[i] = strdup(evsel->name); |
| 40 | if (ev_name[i] == NULL) { |
| 41 | pr_debug("memory allocation failure\n"); |
| 42 | goto out; |
| 43 | } |
| 44 | i++; |
| 45 | } |
| 46 | /* remember grouping info */ |
| 47 | was_group_event = evsel__is_group_event(evlist__first(evlist)); |
| 48 | nr_members = evlist__first(evlist)->core.nr_members; |
| 49 | |
| 50 | ret = evlist__expand_cgroup(evlist, cgrp_str, metric_events, false); |
| 51 | if (ret < 0) { |
| 52 | pr_debug("failed to expand events for cgroups\n"); |
| 53 | goto out; |
| 54 | } |
| 55 | |
| 56 | ret = TEST_FAIL; |
| 57 | if (evlist->core.nr_entries != nr_events * nr_cgrps) { |
| 58 | pr_debug("event count doesn't match\n"); |
| 59 | goto out; |
| 60 | } |
| 61 | |
| 62 | i = 0; |
| 63 | evlist__for_each_entry(evlist, evsel) { |
| 64 | if (strcmp(evsel->name, ev_name[i % nr_events])) { |
| 65 | pr_debug("event name doesn't match:\n"); |
| 66 | pr_debug(" evsel[%d]: %s\n expected: %s\n", |
| 67 | i, evsel->name, ev_name[i % nr_events]); |
| 68 | goto out; |
| 69 | } |
| 70 | if (strcmp(evsel->cgrp->name, cgrp_name[i / nr_events])) { |
| 71 | pr_debug("cgroup name doesn't match:\n"); |
| 72 | pr_debug(" evsel[%d]: %s\n expected: %s\n", |
| 73 | i, evsel->cgrp->name, cgrp_name[i / nr_events]); |
| 74 | goto out; |
| 75 | } |
| 76 | |
| 77 | if ((i % nr_events) == 0) { |
| 78 | if (evsel__is_group_event(evsel) != was_group_event) { |
| 79 | pr_debug("event group doesn't match: got %s, expect %s\n", |
| 80 | evsel__is_group_event(evsel) ? "true" : "false", |
| 81 | was_group_event ? "true" : "false"); |
| 82 | goto out; |
| 83 | } |
| 84 | if (evsel->core.nr_members != nr_members) { |
| 85 | pr_debug("event group member doesn't match: %d vs %d\n", |
| 86 | evsel->core.nr_members, nr_members); |
| 87 | goto out; |
| 88 | } |
| 89 | } |
| 90 | i++; |
| 91 | } |
| 92 | ret = TEST_OK; |
| 93 | |
| 94 | out: for (i = 0; i < nr_events; i++) |
| 95 | free(ev_name[i]); |
| 96 | free(ev_name); |
| 97 | return ret; |
| 98 | } |
| 99 | |
| 100 | static int expand_default_events(void) |
| 101 | { |
| 102 | int ret; |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 103 | struct rblist metric_events; |
Arnaldo Carvalho de Melo | 606e2c2 | 2020-11-30 15:04:05 -0300 | [diff] [blame] | 104 | struct evlist *evlist = evlist__new_default(); |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 105 | |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 106 | TEST_ASSERT_VAL("failed to get evlist", evlist); |
| 107 | |
| 108 | rblist__init(&metric_events); |
| 109 | ret = test_expand_events(evlist, &metric_events); |
| 110 | evlist__delete(evlist); |
| 111 | return ret; |
| 112 | } |
| 113 | |
| 114 | static int expand_group_events(void) |
| 115 | { |
| 116 | int ret; |
| 117 | struct evlist *evlist; |
| 118 | struct rblist metric_events; |
| 119 | struct parse_events_error err; |
| 120 | const char event_str[] = "{cycles,instructions}"; |
| 121 | |
| 122 | symbol_conf.event_group = true; |
| 123 | |
| 124 | evlist = evlist__new(); |
| 125 | TEST_ASSERT_VAL("failed to get evlist", evlist); |
| 126 | |
Ian Rogers | 07eafd4 | 2021-11-07 01:00:01 -0800 | [diff] [blame] | 127 | parse_events_error__init(&err); |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 128 | ret = parse_events(evlist, event_str, &err); |
| 129 | if (ret < 0) { |
| 130 | pr_debug("failed to parse event '%s', err %d, str '%s'\n", |
| 131 | event_str, ret, err.str); |
Ian Rogers | 6c19128 | 2021-11-07 01:00:00 -0800 | [diff] [blame] | 132 | parse_events_error__print(&err, event_str); |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 133 | goto out; |
| 134 | } |
| 135 | |
| 136 | rblist__init(&metric_events); |
| 137 | ret = test_expand_events(evlist, &metric_events); |
| 138 | out: |
Ian Rogers | 07eafd4 | 2021-11-07 01:00:01 -0800 | [diff] [blame] | 139 | parse_events_error__exit(&err); |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 140 | evlist__delete(evlist); |
| 141 | return ret; |
| 142 | } |
| 143 | |
| 144 | static int expand_libpfm_events(void) |
| 145 | { |
| 146 | int ret; |
| 147 | struct evlist *evlist; |
| 148 | struct rblist metric_events; |
Namhyung Kim | 9b0a783 | 2020-10-27 16:28:54 +0900 | [diff] [blame] | 149 | const char event_str[] = "CYCLES"; |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 150 | struct option opt = { |
| 151 | .value = &evlist, |
| 152 | }; |
| 153 | |
| 154 | symbol_conf.event_group = true; |
| 155 | |
| 156 | evlist = evlist__new(); |
| 157 | TEST_ASSERT_VAL("failed to get evlist", evlist); |
| 158 | |
| 159 | ret = parse_libpfm_events_option(&opt, event_str, 0); |
| 160 | if (ret < 0) { |
| 161 | pr_debug("failed to parse libpfm event '%s', err %d\n", |
| 162 | event_str, ret); |
| 163 | goto out; |
| 164 | } |
Arnaldo Carvalho de Melo | e414fd1 | 2020-11-30 14:52:44 -0300 | [diff] [blame] | 165 | if (evlist__empty(evlist)) { |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 166 | pr_debug("libpfm was not enabled\n"); |
| 167 | goto out; |
| 168 | } |
| 169 | |
| 170 | rblist__init(&metric_events); |
| 171 | ret = test_expand_events(evlist, &metric_events); |
| 172 | out: |
| 173 | evlist__delete(evlist); |
| 174 | return ret; |
| 175 | } |
| 176 | |
| 177 | static int expand_metric_events(void) |
| 178 | { |
| 179 | int ret; |
| 180 | struct evlist *evlist; |
| 181 | struct rblist metric_events; |
| 182 | const char metric_str[] = "CPI"; |
Ian Rogers | 1ba3752 | 2022-08-12 16:09:46 -0700 | [diff] [blame] | 183 | const struct pmu_events_table *pme_test; |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 184 | |
| 185 | evlist = evlist__new(); |
| 186 | TEST_ASSERT_VAL("failed to get evlist", evlist); |
| 187 | |
| 188 | rblist__init(&metric_events); |
Ian Rogers | 7ae5c03 | 2022-08-12 16:09:44 -0700 | [diff] [blame] | 189 | pme_test = find_core_events_table("testarch", "testcpu"); |
Ian Rogers | eeac773 | 2022-08-12 16:09:41 -0700 | [diff] [blame] | 190 | ret = metricgroup__parse_groups_test(evlist, pme_test, metric_str, |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 191 | false, false, &metric_events); |
| 192 | if (ret < 0) { |
| 193 | pr_debug("failed to parse '%s' metric\n", metric_str); |
| 194 | goto out; |
| 195 | } |
| 196 | |
| 197 | ret = test_expand_events(evlist, &metric_events); |
| 198 | |
| 199 | out: |
| 200 | metricgroup__rblist_exit(&metric_events); |
| 201 | evlist__delete(evlist); |
| 202 | return ret; |
| 203 | } |
| 204 | |
Ian Rogers | 33f44bf | 2021-11-03 23:41:51 -0700 | [diff] [blame] | 205 | static int test__expand_cgroup_events(struct test_suite *test __maybe_unused, |
Ian Rogers | d68f036 | 2021-11-03 23:41:50 -0700 | [diff] [blame] | 206 | int subtest __maybe_unused) |
Namhyung Kim | 40b74c30 | 2020-09-24 21:44:55 +0900 | [diff] [blame] | 207 | { |
| 208 | int ret; |
| 209 | |
| 210 | ret = expand_default_events(); |
| 211 | TEST_ASSERT_EQUAL("failed to expand default events", ret, 0); |
| 212 | |
| 213 | ret = expand_group_events(); |
| 214 | TEST_ASSERT_EQUAL("failed to expand event group", ret, 0); |
| 215 | |
| 216 | ret = expand_libpfm_events(); |
| 217 | TEST_ASSERT_EQUAL("failed to expand event group", ret, 0); |
| 218 | |
| 219 | ret = expand_metric_events(); |
| 220 | TEST_ASSERT_EQUAL("failed to expand metric events", ret, 0); |
| 221 | |
| 222 | return ret; |
| 223 | } |
Ian Rogers | d68f036 | 2021-11-03 23:41:50 -0700 | [diff] [blame] | 224 | |
| 225 | DEFINE_SUITE("Event expansion for cgroups", expand_cgroup_events); |