perf stat: Move metric list from config to evlist

The rblist of metric_event that then have a list of associated
metric_expr is moved out of the stat_config and into the evlist. This
is done as part of refactoring things for python, having the state
split in two places complicates that implementation. The evlist is
doing the harder work of enabling and disabling events, the metrics
are needed to compute a value and it doesn't seem unreasonable to hang
them from the evlist.

Signed-off-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250710235126.1086011-7-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
Ian Rogers
2025-07-10 16:51:19 -07:00
committed by Namhyung Kim
parent cb336b6aae
commit faebee18d7
15 changed files with 75 additions and 108 deletions

View File

@@ -2136,8 +2136,7 @@ static void perf_sample__fprint_metric(struct perf_script *script,
perf_stat__print_shadow_stats(&stat_config, ev2, perf_stat__print_shadow_stats(&stat_config, ev2,
evsel_script(ev2)->val, evsel_script(ev2)->val,
sample->cpu, sample->cpu,
&ctx, &ctx);
NULL);
} }
evsel_script(leader)->gnum = 0; evsel_script(leader)->gnum = 0;
} }

View File

@@ -1863,8 +1863,7 @@ static int add_default_events(void)
stat_config.metric_no_threshold, stat_config.metric_no_threshold,
stat_config.user_requested_cpu_list, stat_config.user_requested_cpu_list,
stat_config.system_wide, stat_config.system_wide,
stat_config.hardware_aware_grouping, stat_config.hardware_aware_grouping);
&stat_config.metric_events);
goto out; goto out;
} }
@@ -1901,8 +1900,7 @@ static int add_default_events(void)
stat_config.metric_no_threshold, stat_config.metric_no_threshold,
stat_config.user_requested_cpu_list, stat_config.user_requested_cpu_list,
stat_config.system_wide, stat_config.system_wide,
stat_config.hardware_aware_grouping, stat_config.hardware_aware_grouping);
&stat_config.metric_events);
goto out; goto out;
} }
@@ -1939,8 +1937,7 @@ static int add_default_events(void)
/*metric_no_threshold=*/true, /*metric_no_threshold=*/true,
stat_config.user_requested_cpu_list, stat_config.user_requested_cpu_list,
stat_config.system_wide, stat_config.system_wide,
stat_config.hardware_aware_grouping, stat_config.hardware_aware_grouping) < 0) {
&stat_config.metric_events) < 0) {
ret = -1; ret = -1;
goto out; goto out;
} }
@@ -1989,8 +1986,7 @@ static int add_default_events(void)
/*metric_no_threshold=*/true, /*metric_no_threshold=*/true,
stat_config.user_requested_cpu_list, stat_config.user_requested_cpu_list,
stat_config.system_wide, stat_config.system_wide,
stat_config.hardware_aware_grouping, stat_config.hardware_aware_grouping) < 0) {
&stat_config.metric_events) < 0) {
ret = -1; ret = -1;
goto out; goto out;
} }
@@ -1999,6 +1995,9 @@ static int add_default_events(void)
evsel->default_metricgroup = true; evsel->default_metricgroup = true;
evlist__splice_list_tail(evlist, &metric_evlist->core.entries); evlist__splice_list_tail(evlist, &metric_evlist->core.entries);
metricgroup__copy_metric_events(evlist, /*cgrp=*/NULL,
&evlist->metric_events,
&metric_evlist->metric_events);
evlist__delete(metric_evlist); evlist__delete(metric_evlist);
} }
} }
@@ -2053,6 +2052,9 @@ static int add_default_events(void)
} }
parse_events_error__exit(&err); parse_events_error__exit(&err);
evlist__splice_list_tail(evsel_list, &evlist->core.entries); evlist__splice_list_tail(evsel_list, &evlist->core.entries);
metricgroup__copy_metric_events(evsel_list, /*cgrp=*/NULL,
&evsel_list->metric_events,
&evlist->metric_events);
evlist__delete(evlist); evlist__delete(evlist);
return ret; return ret;
} }
@@ -2739,8 +2741,7 @@ int cmd_stat(int argc, const char **argv)
stat_config.metric_no_threshold, stat_config.metric_no_threshold,
stat_config.user_requested_cpu_list, stat_config.user_requested_cpu_list,
stat_config.system_wide, stat_config.system_wide,
stat_config.hardware_aware_grouping, stat_config.hardware_aware_grouping);
&stat_config.metric_events);
zfree(&metrics); zfree(&metrics);
if (ret) { if (ret) {
@@ -2760,8 +2761,7 @@ int cmd_stat(int argc, const char **argv)
goto out; goto out;
} }
if (evlist__expand_cgroup(evsel_list, stat_config.cgroup_list, if (evlist__expand_cgroup(evsel_list, stat_config.cgroup_list, true) < 0) {
&stat_config.metric_events, true) < 0) {
parse_options_usage(stat_usage, stat_options, parse_options_usage(stat_usage, stat_options,
"for-each-cgroup", 0); "for-each-cgroup", 0);
goto out; goto out;
@@ -2936,7 +2936,6 @@ int cmd_stat(int argc, const char **argv)
evlist__delete(evsel_list); evlist__delete(evsel_list);
metricgroup__rblist_exit(&stat_config.metric_events);
evlist__close_control(stat_config.ctl_fd, stat_config.ctl_fd_ack, &stat_config.ctl_fd_close); evlist__close_control(stat_config.ctl_fd, stat_config.ctl_fd_ack, &stat_config.ctl_fd_close);
return status; return status;

View File

@@ -13,8 +13,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static int test_expand_events(struct evlist *evlist, static int test_expand_events(struct evlist *evlist)
struct rblist *metric_events)
{ {
int i, ret = TEST_FAIL; int i, ret = TEST_FAIL;
int nr_events; int nr_events;
@@ -47,7 +46,7 @@ static int test_expand_events(struct evlist *evlist,
was_group_event = evsel__is_group_event(evlist__first(evlist)); was_group_event = evsel__is_group_event(evlist__first(evlist));
nr_members = evlist__first(evlist)->core.nr_members; nr_members = evlist__first(evlist)->core.nr_members;
ret = evlist__expand_cgroup(evlist, cgrp_str, metric_events, false); ret = evlist__expand_cgroup(evlist, cgrp_str, false);
if (ret < 0) { if (ret < 0) {
pr_debug("failed to expand events for cgroups\n"); pr_debug("failed to expand events for cgroups\n");
goto out; goto out;
@@ -100,13 +99,11 @@ out: for (i = 0; i < nr_events; i++)
static int expand_default_events(void) static int expand_default_events(void)
{ {
int ret; int ret;
struct rblist metric_events;
struct evlist *evlist = evlist__new_default(); struct evlist *evlist = evlist__new_default();
TEST_ASSERT_VAL("failed to get evlist", evlist); TEST_ASSERT_VAL("failed to get evlist", evlist);
rblist__init(&metric_events); ret = test_expand_events(evlist);
ret = test_expand_events(evlist, &metric_events);
evlist__delete(evlist); evlist__delete(evlist);
return ret; return ret;
} }
@@ -115,7 +112,6 @@ static int expand_group_events(void)
{ {
int ret; int ret;
struct evlist *evlist; struct evlist *evlist;
struct rblist metric_events;
struct parse_events_error err; struct parse_events_error err;
const char event_str[] = "{cycles,instructions}"; const char event_str[] = "{cycles,instructions}";
@@ -132,8 +128,7 @@ static int expand_group_events(void)
goto out; goto out;
} }
rblist__init(&metric_events); ret = test_expand_events(evlist);
ret = test_expand_events(evlist, &metric_events);
out: out:
parse_events_error__exit(&err); parse_events_error__exit(&err);
evlist__delete(evlist); evlist__delete(evlist);
@@ -144,7 +139,6 @@ static int expand_libpfm_events(void)
{ {
int ret; int ret;
struct evlist *evlist; struct evlist *evlist;
struct rblist metric_events;
const char event_str[] = "CYCLES"; const char event_str[] = "CYCLES";
struct option opt = { struct option opt = {
.value = &evlist, .value = &evlist,
@@ -166,8 +160,7 @@ static int expand_libpfm_events(void)
goto out; goto out;
} }
rblist__init(&metric_events); ret = test_expand_events(evlist);
ret = test_expand_events(evlist, &metric_events);
out: out:
evlist__delete(evlist); evlist__delete(evlist);
return ret; return ret;
@@ -177,25 +170,22 @@ static int expand_metric_events(void)
{ {
int ret; int ret;
struct evlist *evlist; struct evlist *evlist;
struct rblist metric_events;
const char metric_str[] = "CPI"; const char metric_str[] = "CPI";
const struct pmu_metrics_table *pme_test; const struct pmu_metrics_table *pme_test;
evlist = evlist__new(); evlist = evlist__new();
TEST_ASSERT_VAL("failed to get evlist", evlist); TEST_ASSERT_VAL("failed to get evlist", evlist);
rblist__init(&metric_events);
pme_test = find_core_metrics_table("testarch", "testcpu"); pme_test = find_core_metrics_table("testarch", "testcpu");
ret = metricgroup__parse_groups_test(evlist, pme_test, metric_str, &metric_events); ret = metricgroup__parse_groups_test(evlist, pme_test, metric_str);
if (ret < 0) { if (ret < 0) {
pr_debug("failed to parse '%s' metric\n", metric_str); pr_debug("failed to parse '%s' metric\n", metric_str);
goto out; goto out;
} }
ret = test_expand_events(evlist, &metric_events); ret = test_expand_events(evlist);
out: out:
metricgroup__rblist_exit(&metric_events);
evlist__delete(evlist); evlist__delete(evlist);
return ret; return ret;
} }

View File

@@ -45,15 +45,14 @@ static void load_runtime_stat(struct evlist *evlist, struct value *vals)
} }
} }
static double compute_single(struct rblist *metric_events, struct evlist *evlist, static double compute_single(struct evlist *evlist, const char *name)
const char *name)
{ {
struct metric_expr *mexp; struct metric_expr *mexp;
struct metric_event *me; struct metric_event *me;
struct evsel *evsel; struct evsel *evsel;
evlist__for_each_entry(evlist, evsel) { evlist__for_each_entry(evlist, evsel) {
me = metricgroup__lookup(metric_events, evsel, false); me = metricgroup__lookup(&evlist->metric_events, evsel, false);
if (me != NULL) { if (me != NULL) {
list_for_each_entry (mexp, &me->head, nd) { list_for_each_entry (mexp, &me->head, nd) {
if (strcmp(mexp->metric_name, name)) if (strcmp(mexp->metric_name, name))
@@ -69,9 +68,6 @@ static int __compute_metric(const char *name, struct value *vals,
const char *name1, double *ratio1, const char *name1, double *ratio1,
const char *name2, double *ratio2) const char *name2, double *ratio2)
{ {
struct rblist metric_events = {
.nr_entries = 0,
};
const struct pmu_metrics_table *pme_test; const struct pmu_metrics_table *pme_test;
struct perf_cpu_map *cpus; struct perf_cpu_map *cpus;
struct evlist *evlist; struct evlist *evlist;
@@ -95,8 +91,7 @@ static int __compute_metric(const char *name, struct value *vals,
/* Parse the metric into metric_events list. */ /* Parse the metric into metric_events list. */
pme_test = find_core_metrics_table("testarch", "testcpu"); pme_test = find_core_metrics_table("testarch", "testcpu");
err = metricgroup__parse_groups_test(evlist, pme_test, name, err = metricgroup__parse_groups_test(evlist, pme_test, name);
&metric_events);
if (err) if (err)
goto out; goto out;
@@ -109,13 +104,12 @@ static int __compute_metric(const char *name, struct value *vals,
/* And execute the metric */ /* And execute the metric */
if (name1 && ratio1) if (name1 && ratio1)
*ratio1 = compute_single(&metric_events, evlist, name1); *ratio1 = compute_single(evlist, name1);
if (name2 && ratio2) if (name2 && ratio2)
*ratio2 = compute_single(&metric_events, evlist, name2); *ratio2 = compute_single(evlist, name2);
out: out:
/* ... cleanup. */ /* ... cleanup. */
metricgroup__rblist_exit(&metric_events);
evlist__free_stats(evlist); evlist__free_stats(evlist);
perf_cpu_map__put(cpus); perf_cpu_map__put(cpus);
evlist__delete(evlist); evlist__delete(evlist);

View File

@@ -868,9 +868,6 @@ static int test__parsing_callback(const struct pmu_metric *pm,
struct evlist *evlist; struct evlist *evlist;
struct perf_cpu_map *cpus; struct perf_cpu_map *cpus;
struct evsel *evsel; struct evsel *evsel;
struct rblist metric_events = {
.nr_entries = 0,
};
int err = 0; int err = 0;
if (!pm->metric_expr) if (!pm->metric_expr)
@@ -895,7 +892,7 @@ static int test__parsing_callback(const struct pmu_metric *pm,
perf_evlist__set_maps(&evlist->core, cpus, NULL); perf_evlist__set_maps(&evlist->core, cpus, NULL);
err = metricgroup__parse_groups_test(evlist, table, pm->metric_name, &metric_events); err = metricgroup__parse_groups_test(evlist, table, pm->metric_name);
if (err) { if (err) {
if (!strcmp(pm->metric_name, "M1") || !strcmp(pm->metric_name, "M2") || if (!strcmp(pm->metric_name, "M1") || !strcmp(pm->metric_name, "M2") ||
!strcmp(pm->metric_name, "M3")) { !strcmp(pm->metric_name, "M3")) {
@@ -922,7 +919,7 @@ static int test__parsing_callback(const struct pmu_metric *pm,
k++; k++;
} }
evlist__for_each_entry(evlist, evsel) { evlist__for_each_entry(evlist, evsel) {
struct metric_event *me = metricgroup__lookup(&metric_events, evsel, false); struct metric_event *me = metricgroup__lookup(&evlist->metric_events, evsel, false);
if (me != NULL) { if (me != NULL) {
struct metric_expr *mexp; struct metric_expr *mexp;
@@ -944,7 +941,6 @@ static int test__parsing_callback(const struct pmu_metric *pm,
pr_debug("Broken metric %s\n", pm->metric_name); pr_debug("Broken metric %s\n", pm->metric_name);
/* ... cleanup. */ /* ... cleanup. */
metricgroup__rblist_exit(&metric_events);
evlist__free_stats(evlist); evlist__free_stats(evlist);
perf_cpu_map__put(cpus); perf_cpu_map__put(cpus);
evlist__delete(evlist); evlist__delete(evlist);

View File

@@ -413,8 +413,7 @@ static bool has_pattern_string(const char *str)
return !!strpbrk(str, "{}[]()|*+?^$"); return !!strpbrk(str, "{}[]()|*+?^$");
} }
int evlist__expand_cgroup(struct evlist *evlist, const char *str, int evlist__expand_cgroup(struct evlist *evlist, const char *str, bool open_cgroup)
struct rblist *metric_events, bool open_cgroup)
{ {
struct evlist *orig_list, *tmp_list; struct evlist *orig_list, *tmp_list;
struct evsel *pos, *evsel, *leader; struct evsel *pos, *evsel, *leader;
@@ -440,12 +439,8 @@ int evlist__expand_cgroup(struct evlist *evlist, const char *str,
evlist__splice_list_tail(orig_list, &evlist->core.entries); evlist__splice_list_tail(orig_list, &evlist->core.entries);
evlist->core.nr_entries = 0; evlist->core.nr_entries = 0;
if (metric_events) { orig_metric_events = evlist->metric_events;
orig_metric_events = *metric_events; metricgroup__rblist_init(&evlist->metric_events);
rblist__init(metric_events);
} else {
rblist__init(&orig_metric_events);
}
if (has_pattern_string(str)) if (has_pattern_string(str))
prefix_len = match_cgroups(str); prefix_len = match_cgroups(str);
@@ -490,12 +485,10 @@ int evlist__expand_cgroup(struct evlist *evlist, const char *str,
cgroup__put(cgrp); cgroup__put(cgrp);
nr_cgroups++; nr_cgroups++;
if (metric_events) { if (metricgroup__copy_metric_events(tmp_list, cgrp,
if (metricgroup__copy_metric_events(tmp_list, cgrp, &evlist->metric_events,
metric_events, &orig_metric_events) < 0)
&orig_metric_events) < 0) goto out_err;
goto out_err;
}
evlist__splice_list_tail(evlist, &tmp_list->core.entries); evlist__splice_list_tail(evlist, &tmp_list->core.entries);
tmp_list->core.nr_entries = 0; tmp_list->core.nr_entries = 0;
@@ -512,7 +505,7 @@ int evlist__expand_cgroup(struct evlist *evlist, const char *str,
out_err: out_err:
evlist__delete(orig_list); evlist__delete(orig_list);
evlist__delete(tmp_list); evlist__delete(tmp_list);
rblist__exit(&orig_metric_events); metricgroup__rblist_exit(&orig_metric_events);
release_cgroup_list(); release_cgroup_list();
return ret; return ret;

View File

@@ -28,8 +28,7 @@ struct rblist;
struct cgroup *cgroup__new(const char *name, bool do_open); struct cgroup *cgroup__new(const char *name, bool do_open);
struct cgroup *evlist__findnew_cgroup(struct evlist *evlist, const char *name); struct cgroup *evlist__findnew_cgroup(struct evlist *evlist, const char *name);
int evlist__expand_cgroup(struct evlist *evlist, const char *cgroups, int evlist__expand_cgroup(struct evlist *evlist, const char *cgroups, bool open_cgroup);
struct rblist *metric_events, bool open_cgroup);
void evlist__set_default_cgroup(struct evlist *evlist, struct cgroup *cgroup); void evlist__set_default_cgroup(struct evlist *evlist, struct cgroup *cgroup);

View File

@@ -35,6 +35,7 @@
#include "util/util.h" #include "util/util.h"
#include "util/env.h" #include "util/env.h"
#include "util/intel-tpebs.h" #include "util/intel-tpebs.h"
#include "util/metricgroup.h"
#include "util/strbuf.h" #include "util/strbuf.h"
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
@@ -83,6 +84,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus,
evlist->ctl_fd.ack = -1; evlist->ctl_fd.ack = -1;
evlist->ctl_fd.pos = -1; evlist->ctl_fd.pos = -1;
evlist->nr_br_cntr = -1; evlist->nr_br_cntr = -1;
metricgroup__rblist_init(&evlist->metric_events);
} }
struct evlist *evlist__new(void) struct evlist *evlist__new(void)
@@ -173,6 +175,7 @@ static void evlist__purge(struct evlist *evlist)
void evlist__exit(struct evlist *evlist) void evlist__exit(struct evlist *evlist)
{ {
metricgroup__rblist_exit(&evlist->metric_events);
event_enable_timer__exit(&evlist->eet); event_enable_timer__exit(&evlist->eet);
zfree(&evlist->mmap); zfree(&evlist->mmap);
zfree(&evlist->overwrite_mmap); zfree(&evlist->overwrite_mmap);

View File

@@ -12,6 +12,7 @@
#include <perf/evlist.h> #include <perf/evlist.h>
#include "events_stats.h" #include "events_stats.h"
#include "evsel.h" #include "evsel.h"
#include "rblist.h"
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
@@ -86,6 +87,11 @@ struct evlist {
int pos; /* index at evlist core object to check signals */ int pos; /* index at evlist core object to check signals */
} ctl_fd; } ctl_fd;
struct event_enable_timer *eet; struct event_enable_timer *eet;
/**
* @metric_events: A list of struct metric_event which each have a list
* of struct metric_expr.
*/
struct rblist metric_events;
}; };
struct evsel_str_handler { struct evsel_str_handler {

View File

@@ -103,7 +103,7 @@ static void metric_event_delete(struct rblist *rblist __maybe_unused,
free(me); free(me);
} }
static void metricgroup__rblist_init(struct rblist *metric_events) void metricgroup__rblist_init(struct rblist *metric_events)
{ {
rblist__init(metric_events); rblist__init(metric_events);
metric_events->node_cmp = metric_event_cmp; metric_events->node_cmp = metric_event_cmp;
@@ -1323,7 +1323,6 @@ static int parse_groups(struct evlist *perf_evlist,
const char *user_requested_cpu_list, const char *user_requested_cpu_list,
bool system_wide, bool system_wide,
bool fake_pmu, bool fake_pmu,
struct rblist *metric_events_list,
const struct pmu_metrics_table *table) const struct pmu_metrics_table *table)
{ {
struct evlist *combined_evlist = NULL; struct evlist *combined_evlist = NULL;
@@ -1333,8 +1332,6 @@ static int parse_groups(struct evlist *perf_evlist,
bool is_default = !strcmp(str, "Default"); bool is_default = !strcmp(str, "Default");
int ret; int ret;
if (metric_events_list->nr_entries == 0)
metricgroup__rblist_init(metric_events_list);
ret = metricgroup__add_metric_list(pmu, str, metric_no_group, metric_no_threshold, ret = metricgroup__add_metric_list(pmu, str, metric_no_group, metric_no_threshold,
user_requested_cpu_list, user_requested_cpu_list,
system_wide, &metric_list, table); system_wide, &metric_list, table);
@@ -1425,7 +1422,8 @@ static int parse_groups(struct evlist *perf_evlist,
goto out; goto out;
} }
me = metricgroup__lookup(metric_events_list, metric_events[0], true); me = metricgroup__lookup(&perf_evlist->metric_events, metric_events[0],
/*create=*/true);
expr = malloc(sizeof(struct metric_expr)); expr = malloc(sizeof(struct metric_expr));
if (!expr) { if (!expr) {
@@ -1485,8 +1483,7 @@ int metricgroup__parse_groups(struct evlist *perf_evlist,
bool metric_no_threshold, bool metric_no_threshold,
const char *user_requested_cpu_list, const char *user_requested_cpu_list,
bool system_wide, bool system_wide,
bool hardware_aware_grouping, bool hardware_aware_grouping)
struct rblist *metric_events)
{ {
const struct pmu_metrics_table *table = pmu_metrics_table__find(); const struct pmu_metrics_table *table = pmu_metrics_table__find();
@@ -1497,13 +1494,12 @@ int metricgroup__parse_groups(struct evlist *perf_evlist,
return parse_groups(perf_evlist, pmu, str, metric_no_group, metric_no_merge, return parse_groups(perf_evlist, pmu, str, metric_no_group, metric_no_merge,
metric_no_threshold, user_requested_cpu_list, system_wide, metric_no_threshold, user_requested_cpu_list, system_wide,
/*fake_pmu=*/false, metric_events, table); /*fake_pmu=*/false, table);
} }
int metricgroup__parse_groups_test(struct evlist *evlist, int metricgroup__parse_groups_test(struct evlist *evlist,
const struct pmu_metrics_table *table, const struct pmu_metrics_table *table,
const char *str, const char *str)
struct rblist *metric_events)
{ {
return parse_groups(evlist, "all", str, return parse_groups(evlist, "all", str,
/*metric_no_group=*/false, /*metric_no_group=*/false,
@@ -1511,7 +1507,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist,
/*metric_no_threshold=*/false, /*metric_no_threshold=*/false,
/*user_requested_cpu_list=*/NULL, /*user_requested_cpu_list=*/NULL,
/*system_wide=*/false, /*system_wide=*/false,
/*fake_pmu=*/true, metric_events, table); /*fake_pmu=*/true, table);
} }
struct metricgroup__has_metric_data { struct metricgroup__has_metric_data {
@@ -1596,7 +1592,7 @@ int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp,
evsel = evlist__find_evsel(evlist, old_me->evsel->core.idx); evsel = evlist__find_evsel(evlist, old_me->evsel->core.idx);
if (!evsel) if (!evsel)
return -EINVAL; return -EINVAL;
new_me = metricgroup__lookup(new_metric_events, evsel, true); new_me = metricgroup__lookup(new_metric_events, evsel, /*create=*/true);
if (!new_me) if (!new_me)
return -ENOMEM; return -ENOMEM;

View File

@@ -77,18 +77,17 @@ int metricgroup__parse_groups(struct evlist *perf_evlist,
bool metric_no_threshold, bool metric_no_threshold,
const char *user_requested_cpu_list, const char *user_requested_cpu_list,
bool system_wide, bool system_wide,
bool hardware_aware_grouping, bool hardware_aware_grouping);
struct rblist *metric_events);
int metricgroup__parse_groups_test(struct evlist *evlist, int metricgroup__parse_groups_test(struct evlist *evlist,
const struct pmu_metrics_table *table, const struct pmu_metrics_table *table,
const char *str, const char *str);
struct rblist *metric_events);
int metricgroup__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn, int metricgroup__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn,
void *data); void *data);
bool metricgroup__has_metric_or_groups(const char *pmu, const char *metric_or_groups); bool metricgroup__has_metric_or_groups(const char *pmu, const char *metric_or_groups);
unsigned int metricgroups__topdown_max_level(void); unsigned int metricgroups__topdown_max_level(void);
int arch_get_runtimeparam(const struct pmu_metric *pm); int arch_get_runtimeparam(const struct pmu_metric *pm);
void metricgroup__rblist_init(struct rblist *metric_events);
void metricgroup__rblist_exit(struct rblist *metric_events); void metricgroup__rblist_exit(struct rblist *metric_events);
int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp, int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp,

View File

@@ -18,6 +18,7 @@
#include "strbuf.h" #include "strbuf.h"
#include "thread_map.h" #include "thread_map.h"
#include "trace-event.h" #include "trace-event.h"
#include "metricgroup.h"
#include "mmap.h" #include "mmap.h"
#include "util/sample.h" #include "util/sample.h"
#include <internal/lib.h> #include <internal/lib.h>
@@ -1544,6 +1545,9 @@ static PyObject *pyrf_evlist__from_evlist(struct evlist *evlist)
evlist__add(&pevlist->evlist, &pevsel->evsel); evlist__add(&pevlist->evlist, &pevsel->evsel);
} }
metricgroup__copy_metric_events(&pevlist->evlist, /*cgrp=*/NULL,
&pevlist->evlist.metric_events,
&evlist->metric_events);
return (PyObject *)pevlist; return (PyObject *)pevlist;
} }

View File

@@ -899,12 +899,11 @@ static void printout(struct perf_stat_config *config, struct outstate *os,
print_noise(config, os, counter, noise, /*before_metric=*/true); print_noise(config, os, counter, noise, /*before_metric=*/true);
print_running(config, os, run, ena, /*before_metric=*/true); print_running(config, os, run, ena, /*before_metric=*/true);
from = perf_stat__print_shadow_stats_metricgroup(config, counter, aggr_idx, from = perf_stat__print_shadow_stats_metricgroup(config, counter, aggr_idx,
&num, from, &out, &num, from, &out);
&config->metric_events);
} while (from != NULL); } while (from != NULL);
} else } else {
perf_stat__print_shadow_stats(config, counter, uval, aggr_idx, perf_stat__print_shadow_stats(config, counter, uval, aggr_idx, &out);
&out, &config->metric_events); }
} else { } else {
pm(config, os, METRIC_THRESHOLD_UNKNOWN, /*format=*/NULL, /*unit=*/NULL, /*val=*/0); pm(config, os, METRIC_THRESHOLD_UNKNOWN, /*format=*/NULL, /*unit=*/NULL, /*val=*/0);
} }
@@ -1016,7 +1015,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
ena = aggr->counts.ena; ena = aggr->counts.ena;
run = aggr->counts.run; run = aggr->counts.run;
if (perf_stat__skip_metric_event(counter, &config->metric_events, ena, run)) if (perf_stat__skip_metric_event(counter, ena, run))
return; return;
if (val == 0 && should_skip_zero_counter(config, counter, &id)) if (val == 0 && should_skip_zero_counter(config, counter, &id))
@@ -1275,10 +1274,7 @@ static void print_metric_headers(struct perf_stat_config *config,
os.evsel = counter; os.evsel = counter;
perf_stat__print_shadow_stats(config, counter, 0, perf_stat__print_shadow_stats(config, counter, 0, 0, &out);
0,
&out,
&config->metric_events);
} }
if (!config->json_output) if (!config->json_output)

View File

@@ -15,6 +15,7 @@
#include <linux/zalloc.h> #include <linux/zalloc.h>
#include "iostat.h" #include "iostat.h"
#include "util/hashmap.h" #include "util/hashmap.h"
#include "rblist.h"
#include "tool_pmu.h" #include "tool_pmu.h"
struct stats walltime_nsecs_stats; struct stats walltime_nsecs_stats;
@@ -635,14 +636,14 @@ void *perf_stat__print_shadow_stats_metricgroup(struct perf_stat_config *config,
int aggr_idx, int aggr_idx,
int *num, int *num,
void *from, void *from,
struct perf_stat_output_ctx *out, struct perf_stat_output_ctx *out)
struct rblist *metric_events)
{ {
struct metric_event *me; struct metric_event *me;
struct metric_expr *mexp = from; struct metric_expr *mexp = from;
void *ctxp = out->ctx; void *ctxp = out->ctx;
bool header_printed = false; bool header_printed = false;
const char *name = NULL; const char *name = NULL;
struct rblist *metric_events = &evsel->evlist->metric_events;
me = metricgroup__lookup(metric_events, evsel, false); me = metricgroup__lookup(metric_events, evsel, false);
if (me == NULL) if (me == NULL)
@@ -683,8 +684,7 @@ void *perf_stat__print_shadow_stats_metricgroup(struct perf_stat_config *config,
void perf_stat__print_shadow_stats(struct perf_stat_config *config, void perf_stat__print_shadow_stats(struct perf_stat_config *config,
struct evsel *evsel, struct evsel *evsel,
double avg, int aggr_idx, double avg, int aggr_idx,
struct perf_stat_output_ctx *out, struct perf_stat_output_ctx *out)
struct rblist *metric_events)
{ {
typedef void (*stat_print_function_t)(struct perf_stat_config *config, typedef void (*stat_print_function_t)(struct perf_stat_config *config,
const struct evsel *evsel, const struct evsel *evsel,
@@ -735,7 +735,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
} }
perf_stat__print_shadow_stats_metricgroup(config, evsel, aggr_idx, perf_stat__print_shadow_stats_metricgroup(config, evsel, aggr_idx,
&num, NULL, out, metric_events); &num, NULL, out);
if (num == 0) { if (num == 0) {
print_metric(config, ctxp, METRIC_THRESHOLD_UNKNOWN, print_metric(config, ctxp, METRIC_THRESHOLD_UNKNOWN,
@@ -748,7 +748,6 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
* if it's not running or not the metric event. * if it's not running or not the metric event.
*/ */
bool perf_stat__skip_metric_event(struct evsel *evsel, bool perf_stat__skip_metric_event(struct evsel *evsel,
struct rblist *metric_events,
u64 ena, u64 run) u64 ena, u64 run)
{ {
if (!evsel->default_metricgroup) if (!evsel->default_metricgroup)
@@ -757,5 +756,5 @@ bool perf_stat__skip_metric_event(struct evsel *evsel,
if (!ena || !run) if (!ena || !run)
return true; return true;
return !metricgroup__lookup(metric_events, evsel, false); return !metricgroup__lookup(&evsel->evlist->metric_events, evsel, false);
} }

View File

@@ -7,7 +7,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/resource.h> #include <sys/resource.h>
#include "cpumap.h" #include "cpumap.h"
#include "rblist.h"
#include "counts.h" #include "counts.h"
struct perf_cpu_map; struct perf_cpu_map;
@@ -108,7 +107,6 @@ struct perf_stat_config {
aggr_get_id_t aggr_get_id; aggr_get_id_t aggr_get_id;
struct cpu_aggr_map *cpus_aggr_map; struct cpu_aggr_map *cpus_aggr_map;
u64 *walltime_run; u64 *walltime_run;
struct rblist metric_events;
int ctl_fd; int ctl_fd;
int ctl_fd_ack; int ctl_fd_ack;
bool ctl_fd_close; bool ctl_fd_close;
@@ -187,18 +185,14 @@ struct perf_stat_output_ctx {
void perf_stat__print_shadow_stats(struct perf_stat_config *config, void perf_stat__print_shadow_stats(struct perf_stat_config *config,
struct evsel *evsel, struct evsel *evsel,
double avg, int aggr_idx, double avg, int aggr_idx,
struct perf_stat_output_ctx *out, struct perf_stat_output_ctx *out);
struct rblist *metric_events); bool perf_stat__skip_metric_event(struct evsel *evsel, u64 ena, u64 run);
bool perf_stat__skip_metric_event(struct evsel *evsel,
struct rblist *metric_events,
u64 ena, u64 run);
void *perf_stat__print_shadow_stats_metricgroup(struct perf_stat_config *config, void *perf_stat__print_shadow_stats_metricgroup(struct perf_stat_config *config,
struct evsel *evsel, struct evsel *evsel,
int aggr_idx, int aggr_idx,
int *num, int *num,
void *from, void *from,
struct perf_stat_output_ctx *out, struct perf_stat_output_ctx *out);
struct rblist *metric_events);
int evlist__alloc_stats(struct perf_stat_config *config, int evlist__alloc_stats(struct perf_stat_config *config,
struct evlist *evlist, bool alloc_raw); struct evlist *evlist, bool alloc_raw);