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 12740b74c30SNamhyung Kim ret = parse_events(evlist, event_str, &err); 12840b74c30SNamhyung Kim if (ret < 0) { 12940b74c30SNamhyung Kim pr_debug("failed to parse event '%s', err %d, str '%s'\n", 13040b74c30SNamhyung Kim event_str, ret, err.str); 131*6c191289SIan Rogers parse_events_error__print(&err, event_str); 13240b74c30SNamhyung Kim goto out; 13340b74c30SNamhyung Kim } 13440b74c30SNamhyung Kim 13540b74c30SNamhyung Kim rblist__init(&metric_events); 13640b74c30SNamhyung Kim ret = test_expand_events(evlist, &metric_events); 13740b74c30SNamhyung Kim out: 13840b74c30SNamhyung Kim evlist__delete(evlist); 13940b74c30SNamhyung Kim return ret; 14040b74c30SNamhyung Kim } 14140b74c30SNamhyung Kim 14240b74c30SNamhyung Kim static int expand_libpfm_events(void) 14340b74c30SNamhyung Kim { 14440b74c30SNamhyung Kim int ret; 14540b74c30SNamhyung Kim struct evlist *evlist; 14640b74c30SNamhyung Kim struct rblist metric_events; 1479b0a7836SNamhyung Kim const char event_str[] = "CYCLES"; 14840b74c30SNamhyung Kim struct option opt = { 14940b74c30SNamhyung Kim .value = &evlist, 15040b74c30SNamhyung Kim }; 15140b74c30SNamhyung Kim 15240b74c30SNamhyung Kim symbol_conf.event_group = true; 15340b74c30SNamhyung Kim 15440b74c30SNamhyung Kim evlist = evlist__new(); 15540b74c30SNamhyung Kim TEST_ASSERT_VAL("failed to get evlist", evlist); 15640b74c30SNamhyung Kim 15740b74c30SNamhyung Kim ret = parse_libpfm_events_option(&opt, event_str, 0); 15840b74c30SNamhyung Kim if (ret < 0) { 15940b74c30SNamhyung Kim pr_debug("failed to parse libpfm event '%s', err %d\n", 16040b74c30SNamhyung Kim event_str, ret); 16140b74c30SNamhyung Kim goto out; 16240b74c30SNamhyung Kim } 163e414fd1aSArnaldo Carvalho de Melo if (evlist__empty(evlist)) { 16440b74c30SNamhyung Kim pr_debug("libpfm was not enabled\n"); 16540b74c30SNamhyung Kim goto out; 16640b74c30SNamhyung Kim } 16740b74c30SNamhyung Kim 16840b74c30SNamhyung Kim rblist__init(&metric_events); 16940b74c30SNamhyung Kim ret = test_expand_events(evlist, &metric_events); 17040b74c30SNamhyung Kim out: 17140b74c30SNamhyung Kim evlist__delete(evlist); 17240b74c30SNamhyung Kim return ret; 17340b74c30SNamhyung Kim } 17440b74c30SNamhyung Kim 17540b74c30SNamhyung Kim static int expand_metric_events(void) 17640b74c30SNamhyung Kim { 17740b74c30SNamhyung Kim int ret; 17840b74c30SNamhyung Kim struct evlist *evlist; 17940b74c30SNamhyung Kim struct rblist metric_events; 18040b74c30SNamhyung Kim const char metric_str[] = "CPI"; 18140b74c30SNamhyung Kim 18240b74c30SNamhyung Kim struct pmu_event pme_test[] = { 18340b74c30SNamhyung Kim { 18440b74c30SNamhyung Kim .metric_expr = "instructions / cycles", 18540b74c30SNamhyung Kim .metric_name = "IPC", 18640b74c30SNamhyung Kim }, 18740b74c30SNamhyung Kim { 18840b74c30SNamhyung Kim .metric_expr = "1 / IPC", 18940b74c30SNamhyung Kim .metric_name = "CPI", 19040b74c30SNamhyung Kim }, 19140b74c30SNamhyung Kim { 19240b74c30SNamhyung Kim .metric_expr = NULL, 19340b74c30SNamhyung Kim .metric_name = NULL, 19440b74c30SNamhyung Kim }, 19540b74c30SNamhyung Kim }; 1960ec43c08SIan Rogers const struct pmu_events_map ev_map = { 19740b74c30SNamhyung Kim .cpuid = "test", 19840b74c30SNamhyung Kim .version = "1", 19940b74c30SNamhyung Kim .type = "core", 20040b74c30SNamhyung Kim .table = pme_test, 20140b74c30SNamhyung Kim }; 20240b74c30SNamhyung Kim 20340b74c30SNamhyung Kim evlist = evlist__new(); 20440b74c30SNamhyung Kim TEST_ASSERT_VAL("failed to get evlist", evlist); 20540b74c30SNamhyung Kim 20640b74c30SNamhyung Kim rblist__init(&metric_events); 20740b74c30SNamhyung Kim ret = metricgroup__parse_groups_test(evlist, &ev_map, metric_str, 20840b74c30SNamhyung Kim false, false, &metric_events); 20940b74c30SNamhyung Kim if (ret < 0) { 21040b74c30SNamhyung Kim pr_debug("failed to parse '%s' metric\n", metric_str); 21140b74c30SNamhyung Kim goto out; 21240b74c30SNamhyung Kim } 21340b74c30SNamhyung Kim 21440b74c30SNamhyung Kim ret = test_expand_events(evlist, &metric_events); 21540b74c30SNamhyung Kim 21640b74c30SNamhyung Kim out: 21740b74c30SNamhyung Kim metricgroup__rblist_exit(&metric_events); 21840b74c30SNamhyung Kim evlist__delete(evlist); 21940b74c30SNamhyung Kim return ret; 22040b74c30SNamhyung Kim } 22140b74c30SNamhyung Kim 22240b74c30SNamhyung Kim int test__expand_cgroup_events(struct test *test __maybe_unused, 22340b74c30SNamhyung Kim int subtest __maybe_unused) 22440b74c30SNamhyung Kim { 22540b74c30SNamhyung Kim int ret; 22640b74c30SNamhyung Kim 22740b74c30SNamhyung Kim ret = expand_default_events(); 22840b74c30SNamhyung Kim TEST_ASSERT_EQUAL("failed to expand default events", ret, 0); 22940b74c30SNamhyung Kim 23040b74c30SNamhyung Kim ret = expand_group_events(); 23140b74c30SNamhyung Kim TEST_ASSERT_EQUAL("failed to expand event group", ret, 0); 23240b74c30SNamhyung Kim 23340b74c30SNamhyung Kim ret = expand_libpfm_events(); 23440b74c30SNamhyung Kim TEST_ASSERT_EQUAL("failed to expand event group", ret, 0); 23540b74c30SNamhyung Kim 23640b74c30SNamhyung Kim ret = expand_metric_events(); 23740b74c30SNamhyung Kim TEST_ASSERT_EQUAL("failed to expand metric events", ret, 0); 23840b74c30SNamhyung Kim 23940b74c30SNamhyung Kim return ret; 24040b74c30SNamhyung Kim } 241