xref: /kernel/linux/linux-5.10/tools/perf/tests/pfm.c (revision 8c2ecf20)
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
15static int test__pfm_events(void);
16static int test__pfm_group(void);
17#endif
18
19static 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
36static 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
47static 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
107static 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 = 0,
135			.nr_groups = 0,
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
160	for (i = 0; i < ARRAY_SIZE(table); i++) {
161		evlist = evlist__new();
162		if (evlist == NULL)
163			return -ENOMEM;
164
165		opt.value = evlist;
166		parse_libpfm_events_option(&opt,
167					table[i].events,
168					0);
169		TEST_ASSERT_EQUAL(table[i].events,
170				count_pfm_events(&evlist->core),
171				table[i].nr_events);
172		TEST_ASSERT_EQUAL(table[i].events,
173				evlist->nr_groups,
174				table[i].nr_groups);
175
176		evlist__delete(evlist);
177	}
178	return 0;
179}
180#endif
181
182const char *test__pfm_subtest_get_desc(int i)
183{
184	if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
185		return NULL;
186	return pfm_testcase_table[i].desc;
187}
188
189int test__pfm_subtest_get_nr(void)
190{
191	return (int)ARRAY_SIZE(pfm_testcase_table);
192}
193
194int test__pfm(struct test *test __maybe_unused, int i __maybe_unused)
195{
196#ifdef HAVE_LIBPFM
197	if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
198		return TEST_FAIL;
199	return pfm_testcase_table[i].func();
200#else
201	return TEST_SKIP;
202#endif
203}
204