xref: /kernel/linux/linux-5.10/tools/perf/tests/pfm.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Test support for libpfm4 event encodings.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright 2020 Google LLC.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#include "tests.h"
88c2ecf20Sopenharmony_ci#include "util/debug.h"
98c2ecf20Sopenharmony_ci#include "util/evlist.h"
108c2ecf20Sopenharmony_ci#include "util/pfm.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/kernel.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#ifdef HAVE_LIBPFM
158c2ecf20Sopenharmony_cistatic int test__pfm_events(void);
168c2ecf20Sopenharmony_cistatic int test__pfm_group(void);
178c2ecf20Sopenharmony_ci#endif
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cistatic const struct {
208c2ecf20Sopenharmony_ci	int (*func)(void);
218c2ecf20Sopenharmony_ci	const char *desc;
228c2ecf20Sopenharmony_ci} pfm_testcase_table[] = {
238c2ecf20Sopenharmony_ci#ifdef HAVE_LIBPFM
248c2ecf20Sopenharmony_ci	{
258c2ecf20Sopenharmony_ci		.func = test__pfm_events,
268c2ecf20Sopenharmony_ci		.desc = "test of individual --pfm-events",
278c2ecf20Sopenharmony_ci	},
288c2ecf20Sopenharmony_ci	{
298c2ecf20Sopenharmony_ci		.func = test__pfm_group,
308c2ecf20Sopenharmony_ci		.desc = "test groups of --pfm-events",
318c2ecf20Sopenharmony_ci	},
328c2ecf20Sopenharmony_ci#endif
338c2ecf20Sopenharmony_ci};
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#ifdef HAVE_LIBPFM
368c2ecf20Sopenharmony_cistatic int count_pfm_events(struct perf_evlist *evlist)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci	struct perf_evsel *evsel;
398c2ecf20Sopenharmony_ci	int count = 0;
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	perf_evlist__for_each_entry(evlist, evsel) {
428c2ecf20Sopenharmony_ci		count++;
438c2ecf20Sopenharmony_ci	}
448c2ecf20Sopenharmony_ci	return count;
458c2ecf20Sopenharmony_ci}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_cistatic int test__pfm_events(void)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	struct evlist *evlist;
508c2ecf20Sopenharmony_ci	struct option opt;
518c2ecf20Sopenharmony_ci	size_t i;
528c2ecf20Sopenharmony_ci	const struct {
538c2ecf20Sopenharmony_ci		const char *events;
548c2ecf20Sopenharmony_ci		int nr_events;
558c2ecf20Sopenharmony_ci	} table[] = {
568c2ecf20Sopenharmony_ci		{
578c2ecf20Sopenharmony_ci			.events = "",
588c2ecf20Sopenharmony_ci			.nr_events = 0,
598c2ecf20Sopenharmony_ci		},
608c2ecf20Sopenharmony_ci		{
618c2ecf20Sopenharmony_ci			.events = "instructions",
628c2ecf20Sopenharmony_ci			.nr_events = 1,
638c2ecf20Sopenharmony_ci		},
648c2ecf20Sopenharmony_ci		{
658c2ecf20Sopenharmony_ci			.events = "instructions,cycles",
668c2ecf20Sopenharmony_ci			.nr_events = 2,
678c2ecf20Sopenharmony_ci		},
688c2ecf20Sopenharmony_ci		{
698c2ecf20Sopenharmony_ci			.events = "stereolab",
708c2ecf20Sopenharmony_ci			.nr_events = 0,
718c2ecf20Sopenharmony_ci		},
728c2ecf20Sopenharmony_ci		{
738c2ecf20Sopenharmony_ci			.events = "instructions,instructions",
748c2ecf20Sopenharmony_ci			.nr_events = 2,
758c2ecf20Sopenharmony_ci		},
768c2ecf20Sopenharmony_ci		{
778c2ecf20Sopenharmony_ci			.events = "stereolab,instructions",
788c2ecf20Sopenharmony_ci			.nr_events = 0,
798c2ecf20Sopenharmony_ci		},
808c2ecf20Sopenharmony_ci		{
818c2ecf20Sopenharmony_ci			.events = "instructions,stereolab",
828c2ecf20Sopenharmony_ci			.nr_events = 1,
838c2ecf20Sopenharmony_ci		},
848c2ecf20Sopenharmony_ci	};
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(table); i++) {
878c2ecf20Sopenharmony_ci		evlist = evlist__new();
888c2ecf20Sopenharmony_ci		if (evlist == NULL)
898c2ecf20Sopenharmony_ci			return -ENOMEM;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci		opt.value = evlist;
928c2ecf20Sopenharmony_ci		parse_libpfm_events_option(&opt,
938c2ecf20Sopenharmony_ci					table[i].events,
948c2ecf20Sopenharmony_ci					0);
958c2ecf20Sopenharmony_ci		TEST_ASSERT_EQUAL(table[i].events,
968c2ecf20Sopenharmony_ci				count_pfm_events(&evlist->core),
978c2ecf20Sopenharmony_ci				table[i].nr_events);
988c2ecf20Sopenharmony_ci		TEST_ASSERT_EQUAL(table[i].events,
998c2ecf20Sopenharmony_ci				evlist->nr_groups,
1008c2ecf20Sopenharmony_ci				0);
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci		evlist__delete(evlist);
1038c2ecf20Sopenharmony_ci	}
1048c2ecf20Sopenharmony_ci	return 0;
1058c2ecf20Sopenharmony_ci}
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cistatic int test__pfm_group(void)
1088c2ecf20Sopenharmony_ci{
1098c2ecf20Sopenharmony_ci	struct evlist *evlist;
1108c2ecf20Sopenharmony_ci	struct option opt;
1118c2ecf20Sopenharmony_ci	size_t i;
1128c2ecf20Sopenharmony_ci	const struct {
1138c2ecf20Sopenharmony_ci		const char *events;
1148c2ecf20Sopenharmony_ci		int nr_events;
1158c2ecf20Sopenharmony_ci		int nr_groups;
1168c2ecf20Sopenharmony_ci	} table[] = {
1178c2ecf20Sopenharmony_ci		{
1188c2ecf20Sopenharmony_ci			.events = "{},",
1198c2ecf20Sopenharmony_ci			.nr_events = 0,
1208c2ecf20Sopenharmony_ci			.nr_groups = 0,
1218c2ecf20Sopenharmony_ci		},
1228c2ecf20Sopenharmony_ci		{
1238c2ecf20Sopenharmony_ci			.events = "{instructions}",
1248c2ecf20Sopenharmony_ci			.nr_events = 1,
1258c2ecf20Sopenharmony_ci			.nr_groups = 1,
1268c2ecf20Sopenharmony_ci		},
1278c2ecf20Sopenharmony_ci		{
1288c2ecf20Sopenharmony_ci			.events = "{instructions},{}",
1298c2ecf20Sopenharmony_ci			.nr_events = 1,
1308c2ecf20Sopenharmony_ci			.nr_groups = 1,
1318c2ecf20Sopenharmony_ci		},
1328c2ecf20Sopenharmony_ci		{
1338c2ecf20Sopenharmony_ci			.events = "{},{instructions}",
1348c2ecf20Sopenharmony_ci			.nr_events = 0,
1358c2ecf20Sopenharmony_ci			.nr_groups = 0,
1368c2ecf20Sopenharmony_ci		},
1378c2ecf20Sopenharmony_ci		{
1388c2ecf20Sopenharmony_ci			.events = "{instructions},{instructions}",
1398c2ecf20Sopenharmony_ci			.nr_events = 2,
1408c2ecf20Sopenharmony_ci			.nr_groups = 2,
1418c2ecf20Sopenharmony_ci		},
1428c2ecf20Sopenharmony_ci		{
1438c2ecf20Sopenharmony_ci			.events = "{instructions,cycles},{instructions,cycles}",
1448c2ecf20Sopenharmony_ci			.nr_events = 4,
1458c2ecf20Sopenharmony_ci			.nr_groups = 2,
1468c2ecf20Sopenharmony_ci		},
1478c2ecf20Sopenharmony_ci		{
1488c2ecf20Sopenharmony_ci			.events = "{stereolab}",
1498c2ecf20Sopenharmony_ci			.nr_events = 0,
1508c2ecf20Sopenharmony_ci			.nr_groups = 0,
1518c2ecf20Sopenharmony_ci		},
1528c2ecf20Sopenharmony_ci		{
1538c2ecf20Sopenharmony_ci			.events =
1548c2ecf20Sopenharmony_ci			"{instructions,cycles},{instructions,stereolab}",
1558c2ecf20Sopenharmony_ci			.nr_events = 3,
1568c2ecf20Sopenharmony_ci			.nr_groups = 1,
1578c2ecf20Sopenharmony_ci		},
1588c2ecf20Sopenharmony_ci	};
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(table); i++) {
1618c2ecf20Sopenharmony_ci		evlist = evlist__new();
1628c2ecf20Sopenharmony_ci		if (evlist == NULL)
1638c2ecf20Sopenharmony_ci			return -ENOMEM;
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci		opt.value = evlist;
1668c2ecf20Sopenharmony_ci		parse_libpfm_events_option(&opt,
1678c2ecf20Sopenharmony_ci					table[i].events,
1688c2ecf20Sopenharmony_ci					0);
1698c2ecf20Sopenharmony_ci		TEST_ASSERT_EQUAL(table[i].events,
1708c2ecf20Sopenharmony_ci				count_pfm_events(&evlist->core),
1718c2ecf20Sopenharmony_ci				table[i].nr_events);
1728c2ecf20Sopenharmony_ci		TEST_ASSERT_EQUAL(table[i].events,
1738c2ecf20Sopenharmony_ci				evlist->nr_groups,
1748c2ecf20Sopenharmony_ci				table[i].nr_groups);
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci		evlist__delete(evlist);
1778c2ecf20Sopenharmony_ci	}
1788c2ecf20Sopenharmony_ci	return 0;
1798c2ecf20Sopenharmony_ci}
1808c2ecf20Sopenharmony_ci#endif
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ciconst char *test__pfm_subtest_get_desc(int i)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
1858c2ecf20Sopenharmony_ci		return NULL;
1868c2ecf20Sopenharmony_ci	return pfm_testcase_table[i].desc;
1878c2ecf20Sopenharmony_ci}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ciint test__pfm_subtest_get_nr(void)
1908c2ecf20Sopenharmony_ci{
1918c2ecf20Sopenharmony_ci	return (int)ARRAY_SIZE(pfm_testcase_table);
1928c2ecf20Sopenharmony_ci}
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ciint test__pfm(struct test *test __maybe_unused, int i __maybe_unused)
1958c2ecf20Sopenharmony_ci{
1968c2ecf20Sopenharmony_ci#ifdef HAVE_LIBPFM
1978c2ecf20Sopenharmony_ci	if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
1988c2ecf20Sopenharmony_ci		return TEST_FAIL;
1998c2ecf20Sopenharmony_ci	return pfm_testcase_table[i].func();
2008c2ecf20Sopenharmony_ci#else
2018c2ecf20Sopenharmony_ci	return TEST_SKIP;
2028c2ecf20Sopenharmony_ci#endif
2038c2ecf20Sopenharmony_ci}
204