linux/tools/perf/tests/expand-cgroup.c

225 lines
5.4 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0
#include "tests.h"
#include "debug.h"
#include "evlist.h"
#include "cgroup.h"
#include "rblist.h"
#include "metricgroup.h"
#include "parse-events.h"
#include "pmu-events/pmu-events.h"
#include "pfm.h"
#include <subcmd/parse-options.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int test_expand_events(struct evlist *evlist,
struct rblist *metric_events)
{
int i, ret = TEST_FAIL;
int nr_events;
bool was_group_event;
int nr_members; /* for the first evsel only */
const char cgrp_str[] = "A,B,C";
const char *cgrp_name[] = { "A", "B", "C" };
int nr_cgrps = ARRAY_SIZE(cgrp_name);
char **ev_name;
struct evsel *evsel;
TEST_ASSERT_VAL("evlist is empty", !evlist__empty(evlist));
nr_events = evlist->core.nr_entries;
ev_name = calloc(nr_events, sizeof(*ev_name));
if (ev_name == NULL) {
pr_debug("memory allocation failure\n");
return TEST_FAIL;
}
i = 0;
evlist__for_each_entry(evlist, evsel) {
ev_name[i] = strdup(evsel->name);
if (ev_name[i] == NULL) {
pr_debug("memory allocation failure\n");
goto out;
}
i++;
}
/* remember grouping info */
was_group_event = evsel__is_group_event(evlist__first(evlist));
nr_members = evlist__first(evlist)->core.nr_members;
ret = evlist__expand_cgroup(evlist, cgrp_str, metric_events, false);
if (ret < 0) {
pr_debug("failed to expand events for cgroups\n");
goto out;
}
ret = TEST_FAIL;
if (evlist->core.nr_entries != nr_events * nr_cgrps) {
pr_debug("event count doesn't match\n");
goto out;
}
i = 0;
evlist__for_each_entry(evlist, evsel) {
if (!evsel__name_is(evsel, ev_name[i % nr_events])) {
pr_debug("event name doesn't match:\n");
pr_debug(" evsel[%d]: %s\n expected: %s\n",
i, evsel->name, ev_name[i % nr_events]);
goto out;
}
if (strcmp(evsel->cgrp->name, cgrp_name[i / nr_events])) {
pr_debug("cgroup name doesn't match:\n");
pr_debug(" evsel[%d]: %s\n expected: %s\n",
i, evsel->cgrp->name, cgrp_name[i / nr_events]);
goto out;
}
if ((i % nr_events) == 0) {
if (evsel__is_group_event(evsel) != was_group_event) {
pr_debug("event group doesn't match: got %s, expect %s\n",
evsel__is_group_event(evsel) ? "true" : "false",
was_group_event ? "true" : "false");
goto out;
}
if (evsel->core.nr_members != nr_members) {
pr_debug("event group member doesn't match: %d vs %d\n",
evsel->core.nr_members, nr_members);
goto out;
}
}
i++;
}
ret = TEST_OK;
out: for (i = 0; i < nr_events; i++)
free(ev_name[i]);
free(ev_name);
return ret;
}
static int expand_default_events(void)
{
int ret;
struct rblist metric_events;
struct evlist *evlist = evlist__new_default();
TEST_ASSERT_VAL("failed to get evlist", evlist);
rblist__init(&metric_events);
ret = test_expand_events(evlist, &metric_events);
evlist__delete(evlist);
return ret;
}
static int expand_group_events(void)
{
int ret;
struct evlist *evlist;
struct rblist metric_events;
struct parse_events_error err;
const char event_str[] = "{cycles,instructions}";
symbol_conf.event_group = true;
evlist = evlist__new();
TEST_ASSERT_VAL("failed to get evlist", evlist);
parse_events_error__init(&err);
ret = parse_events(evlist, event_str, &err);
if (ret < 0) {
pr_debug("failed to parse event '%s', err %d, str '%s'\n",
event_str, ret, err.str);
parse_events_error__print(&err, event_str);
goto out;
}
rblist__init(&metric_events);
ret = test_expand_events(evlist, &metric_events);
out:
parse_events_error__exit(&err);
evlist__delete(evlist);
return ret;
}
static int expand_libpfm_events(void)
{
int ret;
struct evlist *evlist;
struct rblist metric_events;
const char event_str[] = "CYCLES";
struct option opt = {
.value = &evlist,
};
symbol_conf.event_group = true;
evlist = evlist__new();
TEST_ASSERT_VAL("failed to get evlist", evlist);
ret = parse_libpfm_events_option(&opt, event_str, 0);
if (ret < 0) {
pr_debug("failed to parse libpfm event '%s', err %d\n",
event_str, ret);
goto out;
}
if (evlist__empty(evlist)) {
pr_debug("libpfm was not enabled\n");
goto out;
}
rblist__init(&metric_events);
ret = test_expand_events(evlist, &metric_events);
out:
evlist__delete(evlist);
return ret;
}
static int expand_metric_events(void)
{
int ret;
struct evlist *evlist;
struct rblist metric_events;
const char metric_str[] = "CPI";
perf pmu-events: Introduce pmu_metrics_table Add a metrics table that is just a cast from pmu_events_table. This changes the APIs so that event and metric usage of the underlying table is different. For the no jevents case the tables are already separate, later changes will separate the tables for the jevents case. Reviewed-by: Kajol Jain <kjain@linux.ibm.com> Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Caleb Biggers <caleb.biggers@intel.com> Cc: Florian Fischer <florian.fischer@muhq.space> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jing Zhang <renyu.zj@linux.alibaba.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Garry <john.g.garry@oracle.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Kang Minchul <tegongkang@gmail.com> Cc: Kim Phillips <kim.phillips@amd.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mike Leach <mike.leach@linaro.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Perry Taylor <perry.taylor@intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Rob Herring <robh@kernel.org> Cc: Sandipan Das <sandipan.das@amd.com> Cc: Stephane Eranian <eranian@google.com> Cc: Will Deacon <will@kernel.org> Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com> Cc: linux-arm-kernel@lists.infradead.org Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20230126233645.200509-10-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2023-01-27 07:36:39 +08:00
const struct pmu_metrics_table *pme_test;
evlist = evlist__new();
TEST_ASSERT_VAL("failed to get evlist", evlist);
rblist__init(&metric_events);
perf pmu-events: Separate the metrics from events for no jevents Separate the event and metric table when building without jevents. Add find_core_metrics_table and perf_pmu__find_metrics_table while renaming existing utilities to be event specific, so that users can find the right table for their need. Committer notes: Fix the build on aarch64 with: tools/perf/arch/arm64/util/pmu.c @@ -32,7 +32,7 @@ const struct pmu_events_table *pmu_events_table__find(void) - return perf_pmu__find_table(pmu); + return perf_pmu__find_events_table(pmu); Reviewed-by: John Garry <john.g.garry@oracle.com> Reviewed-by: Kajol Jain <kjain@linux.ibm.com> Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Caleb Biggers <caleb.biggers@intel.com> Cc: Florian Fischer <florian.fischer@muhq.space> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jing Zhang <renyu.zj@linux.alibaba.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Kang Minchul <tegongkang@gmail.com> Cc: Kim Phillips <kim.phillips@amd.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mike Leach <mike.leach@linaro.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Perry Taylor <perry.taylor@intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Rob Herring <robh@kernel.org> Cc: Sandipan Das <sandipan.das@amd.com> Cc: Stephane Eranian <eranian@google.com> Cc: Will Deacon <will@kernel.org> Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com> Cc: linux-arm-kernel@lists.infradead.org Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20230126233645.200509-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2023-01-27 07:36:35 +08:00
pme_test = find_core_metrics_table("testarch", "testcpu");
perf metric: Add --metric-no-threshold option Thresholds may need additional events, this can impact things like sharing groups of events to avoid multiplexing. Add a flag to make the threshold calculations optional. The threshold will still be computed if no additional events are necessary. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com> Cc: Andrii Nakryiko <andrii@kernel.org> Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com> Cc: Caleb Biggers <caleb.biggers@intel.com> Cc: Eduard Zingerman <eddyz87@gmail.com> Cc: Florian Fischer <florian.fischer@muhq.space> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jing Zhang <renyu.zj@linux.alibaba.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Garry <john.g.garry@oracle.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Perry Taylor <perry.taylor@intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Sandipan Das <sandipan.das@amd.com> Cc: Sean Christopherson <seanjc@google.com> Cc: Stephane Eranian <eranian@google.com> Cc: Suzuki Poulouse <suzuki.poulose@arm.com> Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-stm32@st-md-mailman.stormreply.com Link: https://lore.kernel.org/r/20230219092848.639226-39-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2023-02-19 17:28:35 +08:00
ret = metricgroup__parse_groups_test(evlist, pme_test, metric_str, &metric_events);
if (ret < 0) {
pr_debug("failed to parse '%s' metric\n", metric_str);
goto out;
}
ret = test_expand_events(evlist, &metric_events);
out:
metricgroup__rblist_exit(&metric_events);
evlist__delete(evlist);
return ret;
}
static int test__expand_cgroup_events(struct test_suite *test __maybe_unused,
int subtest __maybe_unused)
{
int ret;
ret = expand_default_events();
TEST_ASSERT_EQUAL("failed to expand default events", ret, 0);
ret = expand_group_events();
TEST_ASSERT_EQUAL("failed to expand event group", ret, 0);
ret = expand_libpfm_events();
TEST_ASSERT_EQUAL("failed to expand event group", ret, 0);
ret = expand_metric_events();
TEST_ASSERT_EQUAL("failed to expand metric events", ret, 0);
return ret;
}
DEFINE_SUITE("Event expansion for cgroups", expand_cgroup_events);