140b74c30SNamhyung Kim // SPDX-License-Identifier: GPL-2.0 240b74c30SNamhyung Kim #include "tests.h" 340b74c30SNamhyung Kim #include "debug.h" 440b74c30SNamhyung Kim #include "evlist.h" 540b74c30SNamhyung Kim #include "cgroup.h" 640b74c30SNamhyung Kim #include "rblist.h" 740b74c30SNamhyung Kim #include "metricgroup.h" 840b74c30SNamhyung Kim #include "parse-events.h" 940b74c30SNamhyung Kim #include "pmu-events/pmu-events.h" 1040b74c30SNamhyung Kim #include "pfm.h" 1140b74c30SNamhyung Kim #include <subcmd/parse-options.h> 1240b74c30SNamhyung Kim #include <stdio.h> 1340b74c30SNamhyung Kim #include <stdlib.h> 1440b74c30SNamhyung Kim #include <string.h> 1540b74c30SNamhyung Kim 1640b74c30SNamhyung Kim static int test_expand_events(struct evlist *evlist, 1740b74c30SNamhyung Kim struct rblist *metric_events) 1840b74c30SNamhyung Kim { 1940b74c30SNamhyung Kim int i, ret = TEST_FAIL; 2040b74c30SNamhyung Kim int nr_events; 2140b74c30SNamhyung Kim bool was_group_event; 2240b74c30SNamhyung Kim int nr_members; /* for the first evsel only */ 2340b74c30SNamhyung Kim const char cgrp_str[] = "A,B,C"; 2440b74c30SNamhyung Kim const char *cgrp_name[] = { "A", "B", "C" }; 2540b74c30SNamhyung Kim int nr_cgrps = ARRAY_SIZE(cgrp_name); 2640b74c30SNamhyung Kim char **ev_name; 2740b74c30SNamhyung Kim struct evsel *evsel; 2840b74c30SNamhyung Kim 29e414fd1aSArnaldo Carvalho de Melo TEST_ASSERT_VAL("evlist is empty", !evlist__empty(evlist)); 3040b74c30SNamhyung Kim 3140b74c30SNamhyung Kim nr_events = evlist->core.nr_entries; 3240b74c30SNamhyung Kim ev_name = calloc(nr_events, sizeof(*ev_name)); 3340b74c30SNamhyung Kim if (ev_name == NULL) { 3440b74c30SNamhyung Kim pr_debug("memory allocation failure\n"); 3540b74c30SNamhyung Kim return TEST_FAIL; 3640b74c30SNamhyung Kim } 3740b74c30SNamhyung Kim i = 0; 3840b74c30SNamhyung Kim evlist__for_each_entry(evlist, evsel) { 3940b74c30SNamhyung Kim ev_name[i] = strdup(evsel->name); 4040b74c30SNamhyung Kim if (ev_name[i] == NULL) { 4140b74c30SNamhyung Kim pr_debug("memory allocation failure\n"); 4240b74c30SNamhyung Kim goto out; 4340b74c30SNamhyung Kim } 4440b74c30SNamhyung Kim i++; 4540b74c30SNamhyung Kim } 4640b74c30SNamhyung Kim /* remember grouping info */ 4740b74c30SNamhyung Kim was_group_event = evsel__is_group_event(evlist__first(evlist)); 4840b74c30SNamhyung Kim nr_members = evlist__first(evlist)->core.nr_members; 4940b74c30SNamhyung Kim 5040b74c30SNamhyung Kim ret = evlist__expand_cgroup(evlist, cgrp_str, metric_events, false); 5140b74c30SNamhyung Kim if (ret < 0) { 5240b74c30SNamhyung Kim pr_debug("failed to expand events for cgroups\n"); 5340b74c30SNamhyung Kim goto out; 5440b74c30SNamhyung Kim } 5540b74c30SNamhyung Kim 5640b74c30SNamhyung Kim ret = TEST_FAIL; 5740b74c30SNamhyung Kim if (evlist->core.nr_entries != nr_events * nr_cgrps) { 5840b74c30SNamhyung Kim pr_debug("event count doesn't match\n"); 5940b74c30SNamhyung Kim goto out; 6040b74c30SNamhyung Kim } 6140b74c30SNamhyung Kim 6240b74c30SNamhyung Kim i = 0; 6340b74c30SNamhyung Kim evlist__for_each_entry(evlist, evsel) { 6440b74c30SNamhyung Kim if (strcmp(evsel->name, ev_name[i % nr_events])) { 6540b74c30SNamhyung Kim pr_debug("event name doesn't match:\n"); 6640b74c30SNamhyung Kim pr_debug(" evsel[%d]: %s\n expected: %s\n", 6740b74c30SNamhyung Kim i, evsel->name, ev_name[i % nr_events]); 6840b74c30SNamhyung Kim goto out; 6940b74c30SNamhyung Kim } 7040b74c30SNamhyung Kim if (strcmp(evsel->cgrp->name, cgrp_name[i / nr_events])) { 7140b74c30SNamhyung Kim pr_debug("cgroup name doesn't match:\n"); 7240b74c30SNamhyung Kim pr_debug(" evsel[%d]: %s\n expected: %s\n", 7340b74c30SNamhyung Kim i, evsel->cgrp->name, cgrp_name[i / nr_events]); 7440b74c30SNamhyung Kim goto out; 7540b74c30SNamhyung Kim } 7640b74c30SNamhyung Kim 7740b74c30SNamhyung Kim if ((i % nr_events) == 0) { 7840b74c30SNamhyung Kim if (evsel__is_group_event(evsel) != was_group_event) { 7940b74c30SNamhyung Kim pr_debug("event group doesn't match: got %s, expect %s\n", 8040b74c30SNamhyung Kim evsel__is_group_event(evsel) ? "true" : "false", 8140b74c30SNamhyung Kim was_group_event ? "true" : "false"); 8240b74c30SNamhyung Kim goto out; 8340b74c30SNamhyung Kim } 8440b74c30SNamhyung Kim if (evsel->core.nr_members != nr_members) { 8540b74c30SNamhyung Kim pr_debug("event group member doesn't match: %d vs %d\n", 8640b74c30SNamhyung Kim evsel->core.nr_members, nr_members); 8740b74c30SNamhyung Kim goto out; 8840b74c30SNamhyung Kim } 8940b74c30SNamhyung Kim } 9040b74c30SNamhyung Kim i++; 9140b74c30SNamhyung Kim } 9240b74c30SNamhyung Kim ret = TEST_OK; 9340b74c30SNamhyung Kim 9440b74c30SNamhyung Kim out: for (i = 0; i < nr_events; i++) 9540b74c30SNamhyung Kim free(ev_name[i]); 9640b74c30SNamhyung Kim free(ev_name); 9740b74c30SNamhyung Kim return ret; 9840b74c30SNamhyung Kim } 9940b74c30SNamhyung Kim 10040b74c30SNamhyung Kim static int expand_default_events(void) 10140b74c30SNamhyung Kim { 10240b74c30SNamhyung Kim int ret; 10340b74c30SNamhyung Kim struct rblist metric_events; 104606e2c29SArnaldo Carvalho de Melo struct evlist *evlist = evlist__new_default(); 10540b74c30SNamhyung Kim 10640b74c30SNamhyung Kim TEST_ASSERT_VAL("failed to get evlist", evlist); 10740b74c30SNamhyung Kim 10840b74c30SNamhyung Kim rblist__init(&metric_events); 10940b74c30SNamhyung Kim ret = test_expand_events(evlist, &metric_events); 11040b74c30SNamhyung Kim evlist__delete(evlist); 11140b74c30SNamhyung Kim return ret; 11240b74c30SNamhyung Kim } 11340b74c30SNamhyung Kim 11440b74c30SNamhyung Kim static int expand_group_events(void) 11540b74c30SNamhyung Kim { 11640b74c30SNamhyung Kim int ret; 11740b74c30SNamhyung Kim struct evlist *evlist; 11840b74c30SNamhyung Kim struct rblist metric_events; 11940b74c30SNamhyung Kim struct parse_events_error err; 12040b74c30SNamhyung Kim const char event_str[] = "{cycles,instructions}"; 12140b74c30SNamhyung Kim 12240b74c30SNamhyung Kim symbol_conf.event_group = true; 12340b74c30SNamhyung Kim 12440b74c30SNamhyung Kim evlist = evlist__new(); 12540b74c30SNamhyung Kim TEST_ASSERT_VAL("failed to get evlist", evlist); 12640b74c30SNamhyung Kim 12707eafd4eSIan Rogers parse_events_error__init(&err); 12840b74c30SNamhyung Kim ret = parse_events(evlist, event_str, &err); 12940b74c30SNamhyung Kim if (ret < 0) { 13040b74c30SNamhyung Kim pr_debug("failed to parse event '%s', err %d, str '%s'\n", 13140b74c30SNamhyung Kim event_str, ret, err.str); 1326c191289SIan Rogers parse_events_error__print(&err, event_str); 13340b74c30SNamhyung Kim goto out; 13440b74c30SNamhyung Kim } 13540b74c30SNamhyung Kim 13640b74c30SNamhyung Kim rblist__init(&metric_events); 13740b74c30SNamhyung Kim ret = test_expand_events(evlist, &metric_events); 13840b74c30SNamhyung Kim out: 13907eafd4eSIan Rogers parse_events_error__exit(&err); 14040b74c30SNamhyung Kim evlist__delete(evlist); 14140b74c30SNamhyung Kim return ret; 14240b74c30SNamhyung Kim } 14340b74c30SNamhyung Kim 14440b74c30SNamhyung Kim static int expand_libpfm_events(void) 14540b74c30SNamhyung Kim { 14640b74c30SNamhyung Kim int ret; 14740b74c30SNamhyung Kim struct evlist *evlist; 14840b74c30SNamhyung Kim struct rblist metric_events; 1499b0a7836SNamhyung Kim const char event_str[] = "CYCLES"; 15040b74c30SNamhyung Kim struct option opt = { 15140b74c30SNamhyung Kim .value = &evlist, 15240b74c30SNamhyung Kim }; 15340b74c30SNamhyung Kim 15440b74c30SNamhyung Kim symbol_conf.event_group = true; 15540b74c30SNamhyung Kim 15640b74c30SNamhyung Kim evlist = evlist__new(); 15740b74c30SNamhyung Kim TEST_ASSERT_VAL("failed to get evlist", evlist); 15840b74c30SNamhyung Kim 15940b74c30SNamhyung Kim ret = parse_libpfm_events_option(&opt, event_str, 0); 16040b74c30SNamhyung Kim if (ret < 0) { 16140b74c30SNamhyung Kim pr_debug("failed to parse libpfm event '%s', err %d\n", 16240b74c30SNamhyung Kim event_str, ret); 16340b74c30SNamhyung Kim goto out; 16440b74c30SNamhyung Kim } 165e414fd1aSArnaldo Carvalho de Melo if (evlist__empty(evlist)) { 16640b74c30SNamhyung Kim pr_debug("libpfm was not enabled\n"); 16740b74c30SNamhyung Kim goto out; 16840b74c30SNamhyung Kim } 16940b74c30SNamhyung Kim 17040b74c30SNamhyung Kim rblist__init(&metric_events); 17140b74c30SNamhyung Kim ret = test_expand_events(evlist, &metric_events); 17240b74c30SNamhyung Kim out: 17340b74c30SNamhyung Kim evlist__delete(evlist); 17440b74c30SNamhyung Kim return ret; 17540b74c30SNamhyung Kim } 17640b74c30SNamhyung Kim 17740b74c30SNamhyung Kim static int expand_metric_events(void) 17840b74c30SNamhyung Kim { 17940b74c30SNamhyung Kim int ret; 18040b74c30SNamhyung Kim struct evlist *evlist; 18140b74c30SNamhyung Kim struct rblist metric_events; 18240b74c30SNamhyung Kim const char metric_str[] = "CPI"; 183f8ea2c15SIan Rogers const struct pmu_metrics_table *pme_test; 18440b74c30SNamhyung Kim 18540b74c30SNamhyung Kim evlist = evlist__new(); 18640b74c30SNamhyung Kim TEST_ASSERT_VAL("failed to get evlist", evlist); 18740b74c30SNamhyung Kim 18840b74c30SNamhyung Kim rblist__init(&metric_events); 18996d2a746SIan Rogers pme_test = find_core_metrics_table("testarch", "testcpu"); 190*1fd09e29SIan Rogers ret = metricgroup__parse_groups_test(evlist, pme_test, metric_str, &metric_events); 19140b74c30SNamhyung Kim if (ret < 0) { 19240b74c30SNamhyung Kim pr_debug("failed to parse '%s' metric\n", metric_str); 19340b74c30SNamhyung Kim goto out; 19440b74c30SNamhyung Kim } 19540b74c30SNamhyung Kim 19640b74c30SNamhyung Kim ret = test_expand_events(evlist, &metric_events); 19740b74c30SNamhyung Kim 19840b74c30SNamhyung Kim out: 19940b74c30SNamhyung Kim metricgroup__rblist_exit(&metric_events); 20040b74c30SNamhyung Kim evlist__delete(evlist); 20140b74c30SNamhyung Kim return ret; 20240b74c30SNamhyung Kim } 20340b74c30SNamhyung Kim 20433f44bfdSIan Rogers static int test__expand_cgroup_events(struct test_suite *test __maybe_unused, 20540b74c30SNamhyung Kim int subtest __maybe_unused) 20640b74c30SNamhyung Kim { 20740b74c30SNamhyung Kim int ret; 20840b74c30SNamhyung Kim 20940b74c30SNamhyung Kim ret = expand_default_events(); 21040b74c30SNamhyung Kim TEST_ASSERT_EQUAL("failed to expand default events", ret, 0); 21140b74c30SNamhyung Kim 21240b74c30SNamhyung Kim ret = expand_group_events(); 21340b74c30SNamhyung Kim TEST_ASSERT_EQUAL("failed to expand event group", ret, 0); 21440b74c30SNamhyung Kim 21540b74c30SNamhyung Kim ret = expand_libpfm_events(); 21640b74c30SNamhyung Kim TEST_ASSERT_EQUAL("failed to expand event group", ret, 0); 21740b74c30SNamhyung Kim 21840b74c30SNamhyung Kim ret = expand_metric_events(); 21940b74c30SNamhyung Kim TEST_ASSERT_EQUAL("failed to expand metric events", ret, 0); 22040b74c30SNamhyung Kim 22140b74c30SNamhyung Kim return ret; 22240b74c30SNamhyung Kim } 223d68f0365SIan Rogers 224d68f0365SIan Rogers DEFINE_SUITE("Event expansion for cgroups", expand_cgroup_events); 225