diff options
author | Joakim Zhang <qiangqing.zhang@nxp.com> | 2019-08-23 16:06:20 +0800 |
---|---|---|
committer | Joakim Zhang <qiangqing.zhang@nxp.com> | 2019-11-28 12:11:37 +0800 |
commit | b8552bd2eafee7524c13622d24f441c8c26ab06f (patch) | |
tree | 7152c0ff480375adac17795158a5e662c5d38641 /tools | |
parent | 37231434b2f55ca706ecb0a77fb305eef7f4a132 (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.c | 167 |
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; } |