Commit bd3846d0 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo

perf metrics: Be PMU specific for referenced metrics.

Hybrid systems may define the same metric for different PMUs, this can
cause confusion of events. To avoid this make the referenced metric
searches PMU specific, matching that in the table.
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Tested-by: default avatarKan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ahmad Yasin <ahmad.yasin@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Edward Baker <edward.baker@intel.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kang Minchul <tegongkang@gmail.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.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: Rob Herring <robh@kernel.org>
Cc: Samantha Alt <samantha.alt@intel.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20230502223851.2234828-39-irogers@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 5136e43c
...@@ -1794,7 +1794,7 @@ static int add_default_attributes(void) ...@@ -1794,7 +1794,7 @@ static int add_default_attributes(void)
* will use this approach. To determine transaction support * will use this approach. To determine transaction support
* on an architecture test for such a metric name. * on an architecture test for such a metric name.
*/ */
if (!metricgroup__has_metric("transaction")) { if (!metricgroup__has_metric("all", "transaction")) {
pr_err("Missing transaction metrics"); pr_err("Missing transaction metrics");
return -1; return -1;
} }
...@@ -1823,7 +1823,7 @@ static int add_default_attributes(void) ...@@ -1823,7 +1823,7 @@ static int add_default_attributes(void)
smi_reset = true; smi_reset = true;
} }
if (!metricgroup__has_metric("smi")) { if (!metricgroup__has_metric("all", "smi")) {
pr_err("Missing smi metrics"); pr_err("Missing smi metrics");
return -1; return -1;
} }
...@@ -1903,7 +1903,7 @@ static int add_default_attributes(void) ...@@ -1903,7 +1903,7 @@ static int add_default_attributes(void)
* caused by exposing latent bugs. This is fixed properly in: * caused by exposing latent bugs. This is fixed properly in:
* https://lore.kernel.org/lkml/bff481ba-e60a-763f-0aa0-3ee53302c480@linux.intel.com/ * https://lore.kernel.org/lkml/bff481ba-e60a-763f-0aa0-3ee53302c480@linux.intel.com/
*/ */
if (metricgroup__has_metric("TopdownL1") && !perf_pmu__has_hybrid()) { if (metricgroup__has_metric("all", "TopdownL1") && !perf_pmu__has_hybrid()) {
struct evlist *metric_evlist = evlist__new(); struct evlist *metric_evlist = evlist__new();
struct evsel *metric_evsel; struct evsel *metric_evsel;
......
...@@ -51,8 +51,8 @@ _json_event_attributes = [ ...@@ -51,8 +51,8 @@ _json_event_attributes = [
# Attributes that are in pmu_metric rather than pmu_event. # Attributes that are in pmu_metric rather than pmu_event.
_json_metric_attributes = [ _json_metric_attributes = [
'metric_name', 'metric_group', 'metric_expr', 'metric_threshold', 'desc', 'pmu', 'metric_name', 'metric_group', 'metric_expr', 'metric_threshold',
'long_desc', 'unit', 'compat', 'metricgroup_no_group', 'aggr_mode', 'desc', 'long_desc', 'unit', 'compat', 'metricgroup_no_group', 'aggr_mode',
'event_grouping' 'event_grouping'
] ]
# Attributes that are bools or enum int values, encoded as '0', '1',... # Attributes that are bools or enum int values, encoded as '0', '1',...
......
...@@ -51,6 +51,7 @@ struct pmu_event { ...@@ -51,6 +51,7 @@ struct pmu_event {
}; };
struct pmu_metric { struct pmu_metric {
const char *pmu;
const char *metric_name; const char *metric_name;
const char *metric_group; const char *metric_group;
const char *metric_expr; const char *metric_expr;
......
...@@ -123,6 +123,7 @@ struct metric { ...@@ -123,6 +123,7 @@ struct metric {
* within the expression. * within the expression.
*/ */
struct expr_parse_ctx *pctx; struct expr_parse_ctx *pctx;
const char *pmu;
/** The name of the metric such as "IPC". */ /** The name of the metric such as "IPC". */
const char *metric_name; const char *metric_name;
/** Modifier on the metric such as "u" or NULL for none. */ /** Modifier on the metric such as "u" or NULL for none. */
...@@ -216,6 +217,7 @@ static struct metric *metric__new(const struct pmu_metric *pm, ...@@ -216,6 +217,7 @@ static struct metric *metric__new(const struct pmu_metric *pm,
if (!m->pctx) if (!m->pctx)
goto out_err; goto out_err;
m->pmu = pm->pmu ?: "cpu";
m->metric_name = pm->metric_name; m->metric_name = pm->metric_name;
m->modifier = NULL; m->modifier = NULL;
if (modifier) { if (modifier) {
...@@ -259,11 +261,12 @@ static bool contains_metric_id(struct evsel **metric_events, int num_events, ...@@ -259,11 +261,12 @@ static bool contains_metric_id(struct evsel **metric_events, int num_events,
/** /**
* setup_metric_events - Find a group of events in metric_evlist that correspond * setup_metric_events - Find a group of events in metric_evlist that correspond
* to the IDs from a parsed metric expression. * to the IDs from a parsed metric expression.
* @pmu: The PMU for the IDs.
* @ids: the metric IDs to match. * @ids: the metric IDs to match.
* @metric_evlist: the list of perf events. * @metric_evlist: the list of perf events.
* @out_metric_events: holds the created metric events array. * @out_metric_events: holds the created metric events array.
*/ */
static int setup_metric_events(struct hashmap *ids, static int setup_metric_events(const char *pmu, struct hashmap *ids,
struct evlist *metric_evlist, struct evlist *metric_evlist,
struct evsel ***out_metric_events) struct evsel ***out_metric_events)
{ {
...@@ -271,6 +274,7 @@ static int setup_metric_events(struct hashmap *ids, ...@@ -271,6 +274,7 @@ static int setup_metric_events(struct hashmap *ids,
const char *metric_id; const char *metric_id;
struct evsel *ev; struct evsel *ev;
size_t ids_size, matched_events, i; size_t ids_size, matched_events, i;
bool all_pmus = !strcmp(pmu, "all");
*out_metric_events = NULL; *out_metric_events = NULL;
ids_size = hashmap__size(ids); ids_size = hashmap__size(ids);
...@@ -283,6 +287,8 @@ static int setup_metric_events(struct hashmap *ids, ...@@ -283,6 +287,8 @@ static int setup_metric_events(struct hashmap *ids,
evlist__for_each_entry(metric_evlist, ev) { evlist__for_each_entry(metric_evlist, ev) {
struct expr_id_data *val_ptr; struct expr_id_data *val_ptr;
if (!all_pmus && strcmp(ev->pmu_name, pmu))
continue;
/* /*
* Check for duplicate events with the same name. For * Check for duplicate events with the same name. For
* example, uncore_imc/cas_count_read/ will turn into 6 * example, uncore_imc/cas_count_read/ will turn into 6
...@@ -355,8 +361,13 @@ static bool match_metric(const char *n, const char *list) ...@@ -355,8 +361,13 @@ static bool match_metric(const char *n, const char *list)
return false; return false;
} }
static bool match_pm_metric(const struct pmu_metric *pm, const char *metric) static bool match_pm_metric(const struct pmu_metric *pm, const char *pmu, const char *metric)
{ {
const char *pm_pmu = pm->pmu ?: "cpu";
if (strcmp(pmu, "all") && strcmp(pm_pmu, pmu))
return false;
return match_metric(pm->metric_group, metric) || return match_metric(pm->metric_group, metric) ||
match_metric(pm->metric_name, metric); match_metric(pm->metric_name, metric);
} }
...@@ -766,6 +777,7 @@ struct visited_metric { ...@@ -766,6 +777,7 @@ struct visited_metric {
struct metricgroup_add_iter_data { struct metricgroup_add_iter_data {
struct list_head *metric_list; struct list_head *metric_list;
const char *pmu;
const char *metric_name; const char *metric_name;
const char *modifier; const char *modifier;
int *ret; int *ret;
...@@ -779,7 +791,8 @@ struct metricgroup_add_iter_data { ...@@ -779,7 +791,8 @@ struct metricgroup_add_iter_data {
const struct pmu_metrics_table *table; const struct pmu_metrics_table *table;
}; };
static bool metricgroup__find_metric(const char *metric, static bool metricgroup__find_metric(const char *pmu,
const char *metric,
const struct pmu_metrics_table *table, const struct pmu_metrics_table *table,
struct pmu_metric *pm); struct pmu_metric *pm);
...@@ -798,6 +811,7 @@ static int add_metric(struct list_head *metric_list, ...@@ -798,6 +811,7 @@ static int add_metric(struct list_head *metric_list,
* resolve_metric - Locate metrics within the root metric and recursively add * resolve_metric - Locate metrics within the root metric and recursively add
* references to them. * references to them.
* @metric_list: The list the metric is added to. * @metric_list: The list the metric is added to.
* @pmu: The PMU name to resolve metrics on, or "all" for all PMUs.
* @modifier: if non-null event modifiers like "u". * @modifier: if non-null event modifiers like "u".
* @metric_no_group: Should events written to events be grouped "{}" or * @metric_no_group: Should events written to events be grouped "{}" or
* global. Grouping is the default but due to multiplexing the * global. Grouping is the default but due to multiplexing the
...@@ -813,6 +827,7 @@ static int add_metric(struct list_head *metric_list, ...@@ -813,6 +827,7 @@ static int add_metric(struct list_head *metric_list,
* architecture perf is running upon. * architecture perf is running upon.
*/ */
static int resolve_metric(struct list_head *metric_list, static int resolve_metric(struct list_head *metric_list,
const char *pmu,
const char *modifier, const char *modifier,
bool metric_no_group, bool metric_no_group,
bool metric_no_threshold, bool metric_no_threshold,
...@@ -842,7 +857,7 @@ static int resolve_metric(struct list_head *metric_list, ...@@ -842,7 +857,7 @@ static int resolve_metric(struct list_head *metric_list,
hashmap__for_each_entry(root_metric->pctx->ids, cur, bkt) { hashmap__for_each_entry(root_metric->pctx->ids, cur, bkt) {
struct pmu_metric pm; struct pmu_metric pm;
if (metricgroup__find_metric(cur->pkey, table, &pm)) { if (metricgroup__find_metric(pmu, cur->pkey, table, &pm)) {
pending = realloc(pending, pending = realloc(pending,
(pending_cnt + 1) * sizeof(struct to_resolve)); (pending_cnt + 1) * sizeof(struct to_resolve));
if (!pending) if (!pending)
...@@ -993,9 +1008,12 @@ static int __add_metric(struct list_head *metric_list, ...@@ -993,9 +1008,12 @@ static int __add_metric(struct list_head *metric_list,
} }
if (!ret) { if (!ret) {
/* Resolve referenced metrics. */ /* Resolve referenced metrics. */
ret = resolve_metric(metric_list, modifier, metric_no_group, const char *pmu = pm->pmu ?: "cpu";
ret = resolve_metric(metric_list, pmu, modifier, metric_no_group,
metric_no_threshold, user_requested_cpu_list, metric_no_threshold, user_requested_cpu_list,
system_wide, root_metric, &visited_node, table); system_wide, root_metric, &visited_node,
table);
} }
if (ret) { if (ret) {
if (is_root) if (is_root)
...@@ -1008,6 +1026,7 @@ static int __add_metric(struct list_head *metric_list, ...@@ -1008,6 +1026,7 @@ static int __add_metric(struct list_head *metric_list,
} }
struct metricgroup__find_metric_data { struct metricgroup__find_metric_data {
const char *pmu;
const char *metric; const char *metric;
struct pmu_metric *pm; struct pmu_metric *pm;
}; };
...@@ -1017,6 +1036,10 @@ static int metricgroup__find_metric_callback(const struct pmu_metric *pm, ...@@ -1017,6 +1036,10 @@ static int metricgroup__find_metric_callback(const struct pmu_metric *pm,
void *vdata) void *vdata)
{ {
struct metricgroup__find_metric_data *data = vdata; struct metricgroup__find_metric_data *data = vdata;
const char *pm_pmu = pm->pmu ?: "cpu";
if (strcmp(data->pmu, "all") && strcmp(pm_pmu, data->pmu))
return 0;
if (!match_metric(pm->metric_name, data->metric)) if (!match_metric(pm->metric_name, data->metric))
return 0; return 0;
...@@ -1025,11 +1048,13 @@ static int metricgroup__find_metric_callback(const struct pmu_metric *pm, ...@@ -1025,11 +1048,13 @@ static int metricgroup__find_metric_callback(const struct pmu_metric *pm,
return 1; return 1;
} }
static bool metricgroup__find_metric(const char *metric, static bool metricgroup__find_metric(const char *pmu,
const char *metric,
const struct pmu_metrics_table *table, const struct pmu_metrics_table *table,
struct pmu_metric *pm) struct pmu_metric *pm)
{ {
struct metricgroup__find_metric_data data = { struct metricgroup__find_metric_data data = {
.pmu = pmu,
.metric = metric, .metric = metric,
.pm = pm, .pm = pm,
}; };
...@@ -1083,7 +1108,7 @@ static int metricgroup__add_metric_sys_event_iter(const struct pmu_metric *pm, ...@@ -1083,7 +1108,7 @@ static int metricgroup__add_metric_sys_event_iter(const struct pmu_metric *pm,
struct metricgroup_add_iter_data *d = data; struct metricgroup_add_iter_data *d = data;
int ret; int ret;
if (!match_pm_metric(pm, d->metric_name)) if (!match_pm_metric(pm, d->pmu, d->metric_name))
return 0; return 0;
ret = add_metric(d->metric_list, pm, d->modifier, d->metric_no_group, ret = add_metric(d->metric_list, pm, d->modifier, d->metric_no_group,
...@@ -1128,6 +1153,7 @@ static int metric_list_cmp(void *priv __maybe_unused, const struct list_head *l, ...@@ -1128,6 +1153,7 @@ static int metric_list_cmp(void *priv __maybe_unused, const struct list_head *l,
struct metricgroup__add_metric_data { struct metricgroup__add_metric_data {
struct list_head *list; struct list_head *list;
const char *pmu;
const char *metric_name; const char *metric_name;
const char *modifier; const char *modifier;
const char *user_requested_cpu_list; const char *user_requested_cpu_list;
...@@ -1144,7 +1170,7 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm, ...@@ -1144,7 +1170,7 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm,
struct metricgroup__add_metric_data *data = vdata; struct metricgroup__add_metric_data *data = vdata;
int ret = 0; int ret = 0;
if (pm->metric_expr && match_pm_metric(pm, data->metric_name)) { if (pm->metric_expr && match_pm_metric(pm, data->pmu, data->metric_name)) {
bool metric_no_group = data->metric_no_group || bool metric_no_group = data->metric_no_group ||
match_metric(data->metric_name, pm->metricgroup_no_group); match_metric(data->metric_name, pm->metricgroup_no_group);
...@@ -1159,6 +1185,7 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm, ...@@ -1159,6 +1185,7 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm,
/** /**
* metricgroup__add_metric - Find and add a metric, or a metric group. * metricgroup__add_metric - Find and add a metric, or a metric group.
* @pmu: The PMU name to search for metrics on, or "all" for all PMUs.
* @metric_name: The name of the metric or metric group. For example, "IPC" * @metric_name: The name of the metric or metric group. For example, "IPC"
* could be the name of a metric and "TopDownL1" the name of a * could be the name of a metric and "TopDownL1" the name of a
* metric group. * metric group.
...@@ -1172,7 +1199,7 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm, ...@@ -1172,7 +1199,7 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm,
* @table: The table that is searched for metrics, most commonly the table for the * @table: The table that is searched for metrics, most commonly the table for the
* architecture perf is running upon. * architecture perf is running upon.
*/ */
static int metricgroup__add_metric(const char *metric_name, const char *modifier, static int metricgroup__add_metric(const char *pmu, const char *metric_name, const char *modifier,
bool metric_no_group, bool metric_no_threshold, bool metric_no_group, bool metric_no_threshold,
const char *user_requested_cpu_list, const char *user_requested_cpu_list,
bool system_wide, bool system_wide,
...@@ -1186,6 +1213,7 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier ...@@ -1186,6 +1213,7 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier
{ {
struct metricgroup__add_metric_data data = { struct metricgroup__add_metric_data data = {
.list = &list, .list = &list,
.pmu = pmu,
.metric_name = metric_name, .metric_name = metric_name,
.modifier = modifier, .modifier = modifier,
.metric_no_group = metric_no_group, .metric_no_group = metric_no_group,
...@@ -1210,6 +1238,7 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier ...@@ -1210,6 +1238,7 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier
.fn = metricgroup__add_metric_sys_event_iter, .fn = metricgroup__add_metric_sys_event_iter,
.data = (void *) &(struct metricgroup_add_iter_data) { .data = (void *) &(struct metricgroup_add_iter_data) {
.metric_list = &list, .metric_list = &list,
.pmu = pmu,
.metric_name = metric_name, .metric_name = metric_name,
.modifier = modifier, .modifier = modifier,
.metric_no_group = metric_no_group, .metric_no_group = metric_no_group,
...@@ -1239,6 +1268,7 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier ...@@ -1239,6 +1268,7 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier
/** /**
* metricgroup__add_metric_list - Find and add metrics, or metric groups, * metricgroup__add_metric_list - Find and add metrics, or metric groups,
* specified in a list. * specified in a list.
* @pmu: A pmu to restrict the metrics to, or "all" for all PMUS.
* @list: the list of metrics or metric groups. For example, "IPC,CPI,TopDownL1" * @list: the list of metrics or metric groups. For example, "IPC,CPI,TopDownL1"
* would match the IPC and CPI metrics, and TopDownL1 would match all * would match the IPC and CPI metrics, and TopDownL1 would match all
* the metrics in the TopDownL1 group. * the metrics in the TopDownL1 group.
...@@ -1251,7 +1281,8 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier ...@@ -1251,7 +1281,8 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier
* @table: The table that is searched for metrics, most commonly the table for the * @table: The table that is searched for metrics, most commonly the table for the
* architecture perf is running upon. * architecture perf is running upon.
*/ */
static int metricgroup__add_metric_list(const char *list, bool metric_no_group, static int metricgroup__add_metric_list(const char *pmu, const char *list,
bool metric_no_group,
bool metric_no_threshold, bool metric_no_threshold,
const char *user_requested_cpu_list, const char *user_requested_cpu_list,
bool system_wide, struct list_head *metric_list, bool system_wide, struct list_head *metric_list,
...@@ -1270,7 +1301,7 @@ static int metricgroup__add_metric_list(const char *list, bool metric_no_group, ...@@ -1270,7 +1301,7 @@ static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
if (modifier) if (modifier)
*modifier++ = '\0'; *modifier++ = '\0';
ret = metricgroup__add_metric(metric_name, modifier, ret = metricgroup__add_metric(pmu, metric_name, modifier,
metric_no_group, metric_no_threshold, metric_no_group, metric_no_threshold,
user_requested_cpu_list, user_requested_cpu_list,
system_wide, metric_list, table); system_wide, metric_list, table);
...@@ -1460,7 +1491,8 @@ static int parse_ids(bool metric_no_merge, struct perf_pmu *fake_pmu, ...@@ -1460,7 +1491,8 @@ static int parse_ids(bool metric_no_merge, struct perf_pmu *fake_pmu,
return ret; return ret;
} }
static int parse_groups(struct evlist *perf_evlist, const char *str, static int parse_groups(struct evlist *perf_evlist,
const char *pmu, const char *str,
bool metric_no_group, bool metric_no_group,
bool metric_no_merge, bool metric_no_merge,
bool metric_no_threshold, bool metric_no_threshold,
...@@ -1478,7 +1510,7 @@ static int parse_groups(struct evlist *perf_evlist, const char *str, ...@@ -1478,7 +1510,7 @@ static int parse_groups(struct evlist *perf_evlist, const char *str,
if (metric_events_list->nr_entries == 0) if (metric_events_list->nr_entries == 0)
metricgroup__rblist_init(metric_events_list); metricgroup__rblist_init(metric_events_list);
ret = metricgroup__add_metric_list(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);
if (ret) if (ret)
...@@ -1535,6 +1567,11 @@ static int parse_groups(struct evlist *perf_evlist, const char *str, ...@@ -1535,6 +1567,11 @@ static int parse_groups(struct evlist *perf_evlist, const char *str,
strcmp(m->modifier, n->modifier))) strcmp(m->modifier, n->modifier)))
continue; continue;
if ((!m->pmu && n->pmu) ||
(m->pmu && !n->pmu) ||
(m->pmu && n->pmu && strcmp(m->pmu, n->pmu)))
continue;
if (expr__subset_of_ids(n->pctx, m->pctx)) { if (expr__subset_of_ids(n->pctx, m->pctx)) {
pr_debug("Events in '%s' fully contained within '%s'\n", pr_debug("Events in '%s' fully contained within '%s'\n",
m->metric_name, n->metric_name); m->metric_name, n->metric_name);
...@@ -1552,7 +1589,8 @@ static int parse_groups(struct evlist *perf_evlist, const char *str, ...@@ -1552,7 +1589,8 @@ static int parse_groups(struct evlist *perf_evlist, const char *str,
metric_evlist = m->evlist; metric_evlist = m->evlist;
} }
ret = setup_metric_events(m->pctx->ids, metric_evlist, &metric_events); ret = setup_metric_events(fake_pmu ? "all" : m->pmu, m->pctx->ids,
metric_evlist, &metric_events);
if (ret) { if (ret) {
pr_debug("Cannot resolve IDs for %s: %s\n", pr_debug("Cannot resolve IDs for %s: %s\n",
m->metric_name, m->metric_expr); m->metric_name, m->metric_expr);
...@@ -1623,7 +1661,7 @@ int metricgroup__parse_groups(struct evlist *perf_evlist, ...@@ -1623,7 +1661,7 @@ int metricgroup__parse_groups(struct evlist *perf_evlist,
if (!table) if (!table)
return -EINVAL; return -EINVAL;
return parse_groups(perf_evlist, str, metric_no_group, metric_no_merge, return parse_groups(perf_evlist, "all", 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=*/NULL, metric_events, table); /*fake_pmu=*/NULL, metric_events, table);
} }
...@@ -1633,7 +1671,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist, ...@@ -1633,7 +1671,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist,
const char *str, const char *str,
struct rblist *metric_events) struct rblist *metric_events)
{ {
return parse_groups(evlist, str, return parse_groups(evlist, "all", str,
/*metric_no_group=*/false, /*metric_no_group=*/false,
/*metric_no_merge=*/false, /*metric_no_merge=*/false,
/*metric_no_threshold=*/false, /*metric_no_threshold=*/false,
...@@ -1642,28 +1680,32 @@ int metricgroup__parse_groups_test(struct evlist *evlist, ...@@ -1642,28 +1680,32 @@ int metricgroup__parse_groups_test(struct evlist *evlist,
&perf_pmu__fake, metric_events, table); &perf_pmu__fake, metric_events, table);
} }
struct metricgroup__has_metric_data {
const char *pmu;
const char *metric;
};
static int metricgroup__has_metric_callback(const struct pmu_metric *pm, static int metricgroup__has_metric_callback(const struct pmu_metric *pm,
const struct pmu_metrics_table *table __maybe_unused, const struct pmu_metrics_table *table __maybe_unused,
void *vdata) void *vdata)
{ {
const char *metric = vdata; struct metricgroup__has_metric_data *data = vdata;
if (match_metric(pm->metric_name, metric) ||
match_metric(pm->metric_group, metric))
return 1;
return 0; return match_pm_metric(pm, data->pmu, data->metric) ? 1 : 0;
} }
bool metricgroup__has_metric(const char *metric) bool metricgroup__has_metric(const char *pmu, const char *metric)
{ {
const struct pmu_metrics_table *table = pmu_metrics_table__find(); const struct pmu_metrics_table *table = pmu_metrics_table__find();
struct metricgroup__has_metric_data data = {
.pmu = pmu,
.metric = metric,
};
if (!table) if (!table)
return false; return false;
return pmu_metrics_table_for_each_metric(table, metricgroup__has_metric_callback, return pmu_metrics_table_for_each_metric(table, metricgroup__has_metric_callback, &data)
(void *)metric) ? true : false; ? true : false;
} }
static int metricgroup__topdown_max_level_callback(const struct pmu_metric *pm, static int metricgroup__topdown_max_level_callback(const struct pmu_metric *pm,
......
...@@ -80,7 +80,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist, ...@@ -80,7 +80,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist,
struct rblist *metric_events); struct rblist *metric_events);
void metricgroup__print(const struct print_callbacks *print_cb, void *print_state); void metricgroup__print(const struct print_callbacks *print_cb, void *print_state);
bool metricgroup__has_metric(const char *metric); bool metricgroup__has_metric(const char *pmu, const char *metric);
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_exit(struct rblist *metric_events); void metricgroup__rblist_exit(struct rblist *metric_events);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment