Merge remote-tracking branch 'torvalds/master' into perf/core
[linux-2.6-microblaze.git] / tools / perf / tests / pfm.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Test support for libpfm4 event encodings.
4  *
5  * Copyright 2020 Google LLC.
6  */
7 #include "tests.h"
8 #include "util/debug.h"
9 #include "util/evlist.h"
10 #include "util/pfm.h"
11
12 #include <linux/kernel.h>
13
14 #ifdef HAVE_LIBPFM
15 static int test__pfm_events(void);
16 static int test__pfm_group(void);
17 #endif
18
19 static const struct {
20         int (*func)(void);
21         const char *desc;
22 } pfm_testcase_table[] = {
23 #ifdef HAVE_LIBPFM
24         {
25                 .func = test__pfm_events,
26                 .desc = "test of individual --pfm-events",
27         },
28         {
29                 .func = test__pfm_group,
30                 .desc = "test groups of --pfm-events",
31         },
32 #endif
33 };
34
35 #ifdef HAVE_LIBPFM
36 static int count_pfm_events(struct perf_evlist *evlist)
37 {
38         struct perf_evsel *evsel;
39         int count = 0;
40
41         perf_evlist__for_each_entry(evlist, evsel) {
42                 count++;
43         }
44         return count;
45 }
46
47 static int test__pfm_events(void)
48 {
49         struct evlist *evlist;
50         struct option opt;
51         size_t i;
52         const struct {
53                 const char *events;
54                 int nr_events;
55         } table[] = {
56                 {
57                         .events = "",
58                         .nr_events = 0,
59                 },
60                 {
61                         .events = "instructions",
62                         .nr_events = 1,
63                 },
64                 {
65                         .events = "instructions,cycles",
66                         .nr_events = 2,
67                 },
68                 {
69                         .events = "stereolab",
70                         .nr_events = 0,
71                 },
72                 {
73                         .events = "instructions,instructions",
74                         .nr_events = 2,
75                 },
76                 {
77                         .events = "stereolab,instructions",
78                         .nr_events = 0,
79                 },
80                 {
81                         .events = "instructions,stereolab",
82                         .nr_events = 1,
83                 },
84         };
85
86         for (i = 0; i < ARRAY_SIZE(table); i++) {
87                 evlist = evlist__new();
88                 if (evlist == NULL)
89                         return -ENOMEM;
90
91                 opt.value = evlist;
92                 parse_libpfm_events_option(&opt,
93                                         table[i].events,
94                                         0);
95                 TEST_ASSERT_EQUAL(table[i].events,
96                                 count_pfm_events(&evlist->core),
97                                 table[i].nr_events);
98                 TEST_ASSERT_EQUAL(table[i].events,
99                                 evlist->nr_groups,
100                                 0);
101
102                 evlist__delete(evlist);
103         }
104         return 0;
105 }
106
107 static int test__pfm_group(void)
108 {
109         struct evlist *evlist;
110         struct option opt;
111         size_t i;
112         const struct {
113                 const char *events;
114                 int nr_events;
115                 int nr_groups;
116         } table[] = {
117                 {
118                         .events = "{},",
119                         .nr_events = 0,
120                         .nr_groups = 0,
121                 },
122                 {
123                         .events = "{instructions}",
124                         .nr_events = 1,
125                         .nr_groups = 1,
126                 },
127                 {
128                         .events = "{instructions},{}",
129                         .nr_events = 1,
130                         .nr_groups = 1,
131                 },
132                 {
133                         .events = "{},{instructions}",
134                         .nr_events = 1,
135                         .nr_groups = 1,
136                 },
137                 {
138                         .events = "{instructions},{instructions}",
139                         .nr_events = 2,
140                         .nr_groups = 2,
141                 },
142                 {
143                         .events = "{instructions,cycles},{instructions,cycles}",
144                         .nr_events = 4,
145                         .nr_groups = 2,
146                 },
147                 {
148                         .events = "{stereolab}",
149                         .nr_events = 0,
150                         .nr_groups = 0,
151                 },
152                 {
153                         .events =
154                         "{instructions,cycles},{instructions,stereolab}",
155                         .nr_events = 3,
156                         .nr_groups = 1,
157                 },
158                 {
159                         .events = "instructions}",
160                         .nr_events = 1,
161                         .nr_groups = 0,
162                 },
163                 {
164                         .events = "{{instructions}}",
165                         .nr_events = 0,
166                         .nr_groups = 0,
167                 },
168         };
169
170         for (i = 0; i < ARRAY_SIZE(table); i++) {
171                 evlist = evlist__new();
172                 if (evlist == NULL)
173                         return -ENOMEM;
174
175                 opt.value = evlist;
176                 parse_libpfm_events_option(&opt,
177                                         table[i].events,
178                                         0);
179                 TEST_ASSERT_EQUAL(table[i].events,
180                                 count_pfm_events(&evlist->core),
181                                 table[i].nr_events);
182                 TEST_ASSERT_EQUAL(table[i].events,
183                                 evlist->nr_groups,
184                                 table[i].nr_groups);
185
186                 evlist__delete(evlist);
187         }
188         return 0;
189 }
190 #endif
191
192 const char *test__pfm_subtest_get_desc(int i)
193 {
194         if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
195                 return NULL;
196         return pfm_testcase_table[i].desc;
197 }
198
199 int test__pfm_subtest_get_nr(void)
200 {
201         return (int)ARRAY_SIZE(pfm_testcase_table);
202 }
203
204 int test__pfm(struct test *test __maybe_unused, int i __maybe_unused)
205 {
206 #ifdef HAVE_LIBPFM
207         if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
208                 return TEST_FAIL;
209         return pfm_testcase_table[i].func();
210 #else
211         return TEST_SKIP;
212 #endif
213 }