summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJoakim Zhang <qiangqing.zhang@nxp.com>2019-08-23 16:06:20 +0800
committerJoakim Zhang <qiangqing.zhang@nxp.com>2019-11-28 12:11:37 +0800
commitb8552bd2eafee7524c13622d24f441c8c26ab06f (patch)
tree7152c0ff480375adac17795158a5e662c5d38641 /tools
parent37231434b2f55ca706ecb0a77fb305eef7f4a132 (diff)
tools: perf: metricgroup: add metricgroup for each PMU
If we want to add/print metricgroup, we need get pmu evets map via CPUID string, so it is important to get CPUID string. Now in metricgroup, it passes NULL to perf_pmu__find_map(), will never get the pmu events map on ARM64 platforms, due to get_cpuid_str() implement for ARM64 depending on the cpu info of PMU. The CPUID string will not be same on all CPUs on heterogeneous platforms, adding provision(using pmu->cpus) to find cpuid string from associated CPUs of PMU. The implement of get_cpuid_str() for ARM64 has taken heterogeneous platforms into consideration, but metricgroup has not. So it is necessory to add heterogeneous support for metricgroup. When we want to add/print metricgroup, need iterator each PMU then pass the perf_pmu struct to perf_pmu__find_map(). Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/metricgroup.c167
1 files changed, 94 insertions, 73 deletions
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index a7c0424dbda3..d91f22c2bbd7 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -296,83 +296,89 @@ static void metricgroup__print_strlist(struct strlist *metrics, bool raw)
void metricgroup__print(bool metrics, bool metricgroups, char *filter,
bool raw, bool details)
{
- struct pmu_events_map *map = perf_pmu__find_map(NULL);
+ struct pmu_events_map *map;
+ struct perf_pmu *pmu;
struct pmu_event *pe;
int i;
struct rblist groups;
struct rb_node *node, *next;
struct strlist *metriclist = NULL;
- if (!map)
- return;
-
if (!metricgroups) {
metriclist = strlist__new(NULL, NULL);
if (!metriclist)
return;
}
- rblist__init(&groups);
- groups.node_new = mep_new;
- groups.node_cmp = mep_cmp;
- groups.node_delete = mep_delete;
- for (i = 0; ; i++) {
- const char *g;
- pe = &map->table[i];
+ pmu = NULL;
+ while ((pmu = perf_pmu__scan(pmu)) != NULL) {
+ map = perf_pmu__find_map(pmu);
- if (!pe->name && !pe->metric_group && !pe->metric_name)
- break;
- if (!pe->metric_expr)
+ if (!map)
continue;
- g = pe->metric_group;
- if (!g && pe->metric_name) {
- if (pe->name)
+
+ rblist__init(&groups);
+ groups.node_new = mep_new;
+ groups.node_cmp = mep_cmp;
+ groups.node_delete = mep_delete;
+ for (i = 0; ; i++) {
+ const char *g;
+ pe = &map->table[i];
+
+ if (!pe->name && !pe->metric_group && !pe->metric_name)
+ break;
+ if (!pe->metric_expr)
continue;
- g = "No_group";
- }
- if (g) {
- char *omg;
- char *mg = strdup(g);
-
- if (!mg)
- return;
- omg = mg;
- while ((g = strsep(&mg, ";")) != NULL) {
- struct mep *me;
- char *s;
-
- g = skip_spaces(g);
- if (*g == 0)
- g = "No_group";
- if (filter && !strstr(g, filter))
+ g = pe->metric_group;
+ if (!g && pe->metric_name) {
+ if (pe->name)
continue;
- if (raw)
- s = (char *)pe->metric_name;
- else {
- if (asprintf(&s, "%s\n%*s%s]",
- pe->metric_name, 8, "[", pe->desc) < 0)
- return;
-
- if (details) {
+ g = "No_group";
+ }
+ if (g) {
+ char *omg;
+ char *mg = strdup(g);
+
+ if (!mg)
+ return;
+ omg = mg;
+ while ((g = strsep(&mg, ";")) != NULL) {
+ struct mep *me;
+ char *s;
+
+ g = skip_spaces(g);
+ if (*g == 0)
+ g = "No_group";
+ if (filter && !strstr(g, filter))
+ continue;
+ if (raw)
+ s = (char *)pe->metric_name;
+ else {
if (asprintf(&s, "%s\n%*s%s]",
- s, 8, "[", pe->metric_expr) < 0)
+ pe->metric_name, 8, "[", pe->desc) < 0)
return;
- }
- }
- if (!s)
- continue;
+ if (details) {
+ if (asprintf(&s, "%s\n%*s%s]",
+ s, 8, "[", pe->metric_expr) < 0)
+ return;
+ }
+ }
- if (!metricgroups) {
- strlist__add(metriclist, s);
- } else {
- me = mep_lookup(&groups, g);
- if (!me)
+ if (!s)
continue;
- strlist__add(me->metrics, s);
+
+ if (!metricgroups) {
+ strlist__add(metriclist, s);
+ } else {
+ me = mep_lookup(&groups, g);
+ if (!me)
+ continue;
+ strlist__add(me->metrics, s);
+ }
}
+ free(omg);
}
- free(omg);
}
}
@@ -397,16 +403,13 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
}
static int metricgroup__add_metric(const char *metric, struct strbuf *events,
+ struct pmu_events_map *map,
struct list_head *group_list)
{
- struct pmu_events_map *map = perf_pmu__find_map(NULL);
struct pmu_event *pe;
int ret = -EINVAL;
int i, j;
- if (!map)
- return 0;
-
for (i = 0; ; i++) {
pe = &map->table[i];
@@ -468,6 +471,7 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
}
static int metricgroup__add_metric_list(const char *list, struct strbuf *events,
+ struct pmu_events_map *map,
struct list_head *group_list)
{
char *llist, *nlist, *p;
@@ -482,7 +486,7 @@ static int metricgroup__add_metric_list(const char *list, struct strbuf *events,
strbuf_addf(events, "%s", "");
while ((p = strsep(&llist, ",")) != NULL) {
- ret = metricgroup__add_metric(p, events, group_list);
+ ret = metricgroup__add_metric(p, events, map, group_list);
if (ret == -EINVAL) {
fprintf(stderr, "Cannot find metric or group `%s'\n",
p);
@@ -514,14 +518,25 @@ int metricgroup__parse_groups(const struct option *opt,
struct parse_events_error parse_error;
struct evlist *perf_evlist = *(struct evlist **)opt->value;
struct strbuf extra_events;
+ struct pmu_events_map *map;
+ struct perf_pmu *pmu;
LIST_HEAD(group_list);
int ret;
if (metric_events->nr_entries == 0)
metricgroup__rblist_init(metric_events);
- ret = metricgroup__add_metric_list(str, &extra_events, &group_list);
- if (ret)
- return ret;
+
+ pmu = NULL;
+ while ((pmu = perf_pmu__scan(pmu)) != NULL) {
+ map = perf_pmu__find_map(pmu);
+ if (!map)
+ continue;
+
+ ret = metricgroup__add_metric_list(str, &extra_events, map, &group_list);
+ if (ret)
+ return ret;
+ }
+
pr_debug("adding %s\n", extra_events.buf);
memset(&parse_error, 0, sizeof(struct parse_events_error));
ret = parse_events(perf_evlist, extra_events.buf, &parse_error);
@@ -539,22 +554,28 @@ out:
bool metricgroup__has_metric(const char *metric)
{
- struct pmu_events_map *map = perf_pmu__find_map(NULL);
+ struct pmu_events_map *map;
+ struct perf_pmu *pmu;
struct pmu_event *pe;
int i;
- if (!map)
- return false;
-
- for (i = 0; ; i++) {
- pe = &map->table[i];
+ pmu = NULL;
+ while ((pmu = perf_pmu__scan(pmu)) != NULL) {
+ map = perf_pmu__find_map(pmu);
- if (!pe->name && !pe->metric_group && !pe->metric_name)
- break;
- if (!pe->metric_expr)
+ if (!map)
continue;
- if (match_metric(pe->metric_name, metric))
- return true;
+
+ for (i = 0; ; i++) {
+ pe = &map->table[i];
+
+ if (!pe->name && !pe->metric_group && !pe->metric_name)
+ break;
+ if (!pe->metric_expr)
+ continue;
+ if (match_metric(pe->metric_name, metric))
+ return true;
+ }
}
return false;
}