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