diff options
Diffstat (limited to 'tools/perf/util/metricgroup.c')
-rw-r--r-- | tools/perf/util/metricgroup.c | 258 |
1 files changed, 143 insertions, 115 deletions
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 7753c3091478..c08284ccc1b5 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -22,6 +22,7 @@ #include <linux/string.h> #include <linux/zalloc.h> #include <subcmd/parse-options.h> +#include "header.h" struct metric_event *metricgroup__lookup(struct rblist *metric_events, struct evsel *evsel, @@ -302,83 +303,91 @@ 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->socname && soc_version_check(pe->socname)) 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)) + if (!pe->name && !pe->metric_group && !pe->metric_name) + break; + if (!pe->metric_expr) + continue; + 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); } } @@ -405,70 +414,80 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter, static int metricgroup__add_metric(const char *metric, struct strbuf *events, struct list_head *group_list) { - struct pmu_events_map *map = perf_pmu__find_map(NULL); + struct pmu_events_map *map; + struct perf_pmu *pmu; struct pmu_event *pe; int ret = -EINVAL; int i, j; - if (!map) - return 0; - - 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_group, metric) || - match_metric(pe->metric_name, metric)) { - const char **ids; - int idnum; - struct egroup *eg; - bool no_group = false; - pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name); + for (i = 0; ; i++) { + pe = &map->table[i]; - if (expr__find_other(pe->metric_expr, - NULL, &ids, &idnum) < 0) + if (pe->socname && soc_version_check(pe->socname)) continue; - if (events->len > 0) - strbuf_addf(events, ","); - for (j = 0; j < idnum; j++) { - pr_debug("found event %s\n", ids[j]); - /* - * Duration time maps to a software event and can make - * groups not count. Always use it outside a - * group. - */ - if (!strcmp(ids[j], "duration_time")) { - if (j > 0) - strbuf_addf(events, "}:W,"); - strbuf_addf(events, "duration_time"); - no_group = true; + if (!pe->name && !pe->metric_group && !pe->metric_name) + break; + if (!pe->metric_expr) + continue; + if (match_metric(pe->metric_group, metric) || + match_metric(pe->metric_name, metric)) { + const char **ids; + int idnum; + struct egroup *eg; + bool no_group = false; + + pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name); + + if (expr__find_other(pe->metric_expr, + NULL, &ids, &idnum) < 0) continue; + if (events->len > 0) + strbuf_addf(events, ","); + for (j = 0; j < idnum; j++) { + pr_debug("found event %s\n", ids[j]); + /* + * Duration time maps to a software event and can make + * groups not count. Always use it outside a + * group. + */ + if (!strcmp(ids[j], "duration_time")) { + if (j > 0) + strbuf_addf(events, "}:W,"); + strbuf_addf(events, "duration_time"); + no_group = true; + continue; + } + strbuf_addf(events, "%s%s", + j == 0 || no_group ? "{" : ",", + ids[j]); + no_group = false; } - strbuf_addf(events, "%s%s", - j == 0 || no_group ? "{" : ",", - ids[j]); - no_group = false; - } - if (!no_group) - strbuf_addf(events, "}:W"); + if (!no_group) + strbuf_addf(events, "}:W"); - eg = malloc(sizeof(struct egroup)); - if (!eg) { - ret = -ENOMEM; - break; + eg = malloc(sizeof(struct egroup)); + if (!eg) { + ret = -ENOMEM; + return ret; + } + eg->ids = ids; + eg->idnum = idnum; + eg->metric_name = pe->metric_name; + eg->metric_expr = pe->metric_expr; + eg->metric_unit = pe->unit; + list_add_tail(&eg->nd, group_list); + ret = 0; } - eg->ids = ids; - eg->idnum = idnum; - eg->metric_name = pe->metric_name; - eg->metric_expr = pe->metric_expr; - eg->metric_unit = pe->unit; - list_add_tail(&eg->nd, group_list); - ret = 0; } + if (ret == 0) + return ret; } return ret; } @@ -528,6 +547,7 @@ int metricgroup__parse_groups(const struct option *opt, ret = metricgroup__add_metric_list(str, &extra_events, &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); @@ -545,22 +565,30 @@ 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->socname && soc_version_check(pe->socname)) + continue; + 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; } |