metricgroup.c (660842e468dcefb5d1d4fb40ed3abe4d1388dff7) metricgroup.c (1ba3752aec30c04bfb7c82b44332ff98294ec0b8)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2017, Intel Corporation.
4 */
5
6/* Manage metrics and groups of metrics from JSON files */
7
8#include "metricgroup.h"

--- 494 unchanged lines hidden (view full) ---

503};
504
505struct metricgroup_iter_data {
506 pmu_event_iter_fn fn;
507 void *data;
508};
509
510static int metricgroup__sys_event_iter(const struct pmu_event *pe,
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2017, Intel Corporation.
4 */
5
6/* Manage metrics and groups of metrics from JSON files */
7
8#include "metricgroup.h"

--- 494 unchanged lines hidden (view full) ---

503};
504
505struct metricgroup_iter_data {
506 pmu_event_iter_fn fn;
507 void *data;
508};
509
510static int metricgroup__sys_event_iter(const struct pmu_event *pe,
511 const struct pmu_event *table __maybe_unused,
511 const struct pmu_events_table *table,
512 void *data)
513{
514 struct metricgroup_iter_data *d = data;
515 struct perf_pmu *pmu = NULL;
516
517 if (!pe->metric_expr || !pe->compat)
518 return 0;
519

--- 4 unchanged lines hidden (view full) ---

524
525 return d->fn(pe, table, d->data);
526 }
527
528 return 0;
529}
530
531static int metricgroup__print_sys_event_iter(const struct pmu_event *pe,
512 void *data)
513{
514 struct metricgroup_iter_data *d = data;
515 struct perf_pmu *pmu = NULL;
516
517 if (!pe->metric_expr || !pe->compat)
518 return 0;
519

--- 4 unchanged lines hidden (view full) ---

524
525 return d->fn(pe, table, d->data);
526 }
527
528 return 0;
529}
530
531static int metricgroup__print_sys_event_iter(const struct pmu_event *pe,
532 const struct pmu_event *table __maybe_unused,
532 const struct pmu_events_table *table __maybe_unused,
533 void *data)
534{
535 struct metricgroup_print_sys_idata *d = data;
536
537 return metricgroup__print_pmu_event(pe, d->metricgroups, d->filter, d->raw,
538 d->details, d->groups, d->metriclist);
539}
540
541struct metricgroup_print_data {
542 const char *pmu_name;
543 struct strlist *metriclist;
544 char *filter;
545 struct rblist *groups;
546 bool metricgroups;
547 bool raw;
548 bool details;
549};
550
551static int metricgroup__print_callback(const struct pmu_event *pe,
533 void *data)
534{
535 struct metricgroup_print_sys_idata *d = data;
536
537 return metricgroup__print_pmu_event(pe, d->metricgroups, d->filter, d->raw,
538 d->details, d->groups, d->metriclist);
539}
540
541struct metricgroup_print_data {
542 const char *pmu_name;
543 struct strlist *metriclist;
544 char *filter;
545 struct rblist *groups;
546 bool metricgroups;
547 bool raw;
548 bool details;
549};
550
551static int metricgroup__print_callback(const struct pmu_event *pe,
552 const struct pmu_event *table __maybe_unused,
552 const struct pmu_events_table *table __maybe_unused,
553 void *vdata)
554{
555 struct metricgroup_print_data *data = vdata;
556
557 if (!pe->metric_expr)
558 return 0;
559
560 if (data->pmu_name && perf_pmu__is_hybrid(pe->pmu) && strcmp(data->pmu_name, pe->pmu))

--- 5 unchanged lines hidden (view full) ---

566}
567
568void metricgroup__print(bool metrics, bool metricgroups, char *filter,
569 bool raw, bool details, const char *pmu_name)
570{
571 struct rblist groups;
572 struct rb_node *node, *next;
573 struct strlist *metriclist = NULL;
553 void *vdata)
554{
555 struct metricgroup_print_data *data = vdata;
556
557 if (!pe->metric_expr)
558 return 0;
559
560 if (data->pmu_name && perf_pmu__is_hybrid(pe->pmu) && strcmp(data->pmu_name, pe->pmu))

--- 5 unchanged lines hidden (view full) ---

566}
567
568void metricgroup__print(bool metrics, bool metricgroups, char *filter,
569 bool raw, bool details, const char *pmu_name)
570{
571 struct rblist groups;
572 struct rb_node *node, *next;
573 struct strlist *metriclist = NULL;
574 const struct pmu_event *table;
574 const struct pmu_events_table *table;
575
576 if (!metricgroups) {
577 metriclist = strlist__new(NULL, NULL);
578 if (!metriclist)
579 return;
580 }
581
582 rblist__init(&groups);

--- 288 unchanged lines hidden (view full) ---

871 struct list_head *metric_list;
872 const char *metric_name;
873 const char *modifier;
874 int *ret;
875 bool *has_match;
876 bool metric_no_group;
877 struct metric *root_metric;
878 const struct visited_metric *visited;
575
576 if (!metricgroups) {
577 metriclist = strlist__new(NULL, NULL);
578 if (!metriclist)
579 return;
580 }
581
582 rblist__init(&groups);

--- 288 unchanged lines hidden (view full) ---

871 struct list_head *metric_list;
872 const char *metric_name;
873 const char *modifier;
874 int *ret;
875 bool *has_match;
876 bool metric_no_group;
877 struct metric *root_metric;
878 const struct visited_metric *visited;
879 const struct pmu_event *table;
879 const struct pmu_events_table *table;
880};
881
882static int add_metric(struct list_head *metric_list,
883 const struct pmu_event *pe,
884 const char *modifier,
885 bool metric_no_group,
886 struct metric *root_metric,
887 const struct visited_metric *visited,
880};
881
882static int add_metric(struct list_head *metric_list,
883 const struct pmu_event *pe,
884 const char *modifier,
885 bool metric_no_group,
886 struct metric *root_metric,
887 const struct visited_metric *visited,
888 const struct pmu_event *table);
888 const struct pmu_events_table *table);
889
890/**
891 * resolve_metric - Locate metrics within the root metric and recursively add
892 * references to them.
893 * @metric_list: The list the metric is added to.
894 * @modifier: if non-null event modifiers like "u".
895 * @metric_no_group: Should events written to events be grouped "{}" or
896 * global. Grouping is the default but due to multiplexing the

--- 6 unchanged lines hidden (view full) ---

903 * @table: The table that is searched for metrics, most commonly the table for the
904 * architecture perf is running upon.
905 */
906static int resolve_metric(struct list_head *metric_list,
907 const char *modifier,
908 bool metric_no_group,
909 struct metric *root_metric,
910 const struct visited_metric *visited,
889
890/**
891 * resolve_metric - Locate metrics within the root metric and recursively add
892 * references to them.
893 * @metric_list: The list the metric is added to.
894 * @modifier: if non-null event modifiers like "u".
895 * @metric_no_group: Should events written to events be grouped "{}" or
896 * global. Grouping is the default but due to multiplexing the

--- 6 unchanged lines hidden (view full) ---

903 * @table: The table that is searched for metrics, most commonly the table for the
904 * architecture perf is running upon.
905 */
906static int resolve_metric(struct list_head *metric_list,
907 const char *modifier,
908 bool metric_no_group,
909 struct metric *root_metric,
910 const struct visited_metric *visited,
911 const struct pmu_event *table)
911 const struct pmu_events_table *table)
912{
913 struct hashmap_entry *cur;
914 size_t bkt;
915 struct to_resolve {
916 /* The metric to resolve. */
917 const struct pmu_event *pe;
918 /*
919 * The key in the IDs map, this may differ from in case,

--- 61 unchanged lines hidden (view full) ---

981 */
982static int __add_metric(struct list_head *metric_list,
983 const struct pmu_event *pe,
984 const char *modifier,
985 bool metric_no_group,
986 int runtime,
987 struct metric *root_metric,
988 const struct visited_metric *visited,
912{
913 struct hashmap_entry *cur;
914 size_t bkt;
915 struct to_resolve {
916 /* The metric to resolve. */
917 const struct pmu_event *pe;
918 /*
919 * The key in the IDs map, this may differ from in case,

--- 61 unchanged lines hidden (view full) ---

981 */
982static int __add_metric(struct list_head *metric_list,
983 const struct pmu_event *pe,
984 const char *modifier,
985 bool metric_no_group,
986 int runtime,
987 struct metric *root_metric,
988 const struct visited_metric *visited,
989 const struct pmu_event *table)
989 const struct pmu_events_table *table)
990{
991 const struct visited_metric *vm;
992 int ret;
993 bool is_root = !root_metric;
994 struct visited_metric visited_node = {
995 .name = pe->metric_name,
996 .parent = visited,
997 };

--- 74 unchanged lines hidden (view full) ---

1072}
1073
1074struct metricgroup__find_metric_data {
1075 const char *metric;
1076 const struct pmu_event *pe;
1077};
1078
1079static int metricgroup__find_metric_callback(const struct pmu_event *pe,
990{
991 const struct visited_metric *vm;
992 int ret;
993 bool is_root = !root_metric;
994 struct visited_metric visited_node = {
995 .name = pe->metric_name,
996 .parent = visited,
997 };

--- 74 unchanged lines hidden (view full) ---

1072}
1073
1074struct metricgroup__find_metric_data {
1075 const char *metric;
1076 const struct pmu_event *pe;
1077};
1078
1079static int metricgroup__find_metric_callback(const struct pmu_event *pe,
1080 const struct pmu_event *table __maybe_unused,
1080 const struct pmu_events_table *table __maybe_unused,
1081 void *vdata)
1082{
1083 struct metricgroup__find_metric_data *data = vdata;
1084
1085 if (!match_metric(pe->metric_name, data->metric))
1086 return 0;
1087
1088 data->pe = pe;
1089 return -1;
1090}
1091
1092const struct pmu_event *metricgroup__find_metric(const char *metric,
1081 void *vdata)
1082{
1083 struct metricgroup__find_metric_data *data = vdata;
1084
1085 if (!match_metric(pe->metric_name, data->metric))
1086 return 0;
1087
1088 data->pe = pe;
1089 return -1;
1090}
1091
1092const struct pmu_event *metricgroup__find_metric(const char *metric,
1093 const struct pmu_event *table)
1093 const struct pmu_events_table *table)
1094{
1095 struct metricgroup__find_metric_data data = {
1096 .metric = metric,
1097 .pe = NULL,
1098 };
1099
1100 pmu_events_table_for_each_event(table, metricgroup__find_metric_callback, &data);
1101
1102 return data.pe;
1103}
1104
1105static int add_metric(struct list_head *metric_list,
1106 const struct pmu_event *pe,
1107 const char *modifier,
1108 bool metric_no_group,
1109 struct metric *root_metric,
1110 const struct visited_metric *visited,
1094{
1095 struct metricgroup__find_metric_data data = {
1096 .metric = metric,
1097 .pe = NULL,
1098 };
1099
1100 pmu_events_table_for_each_event(table, metricgroup__find_metric_callback, &data);
1101
1102 return data.pe;
1103}
1104
1105static int add_metric(struct list_head *metric_list,
1106 const struct pmu_event *pe,
1107 const char *modifier,
1108 bool metric_no_group,
1109 struct metric *root_metric,
1110 const struct visited_metric *visited,
1111 const struct pmu_event *table)
1111 const struct pmu_events_table *table)
1112{
1113 int ret = 0;
1114
1115 pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
1116
1117 if (!strstr(pe->metric_expr, "?")) {
1118 ret = __add_metric(metric_list, pe, modifier, metric_no_group, 0,
1119 root_metric, visited, table);

--- 11 unchanged lines hidden (view full) ---

1131 ret = __add_metric(metric_list, pe, modifier, metric_no_group, j,
1132 root_metric, visited, table);
1133 }
1134
1135 return ret;
1136}
1137
1138static int metricgroup__add_metric_sys_event_iter(const struct pmu_event *pe,
1112{
1113 int ret = 0;
1114
1115 pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
1116
1117 if (!strstr(pe->metric_expr, "?")) {
1118 ret = __add_metric(metric_list, pe, modifier, metric_no_group, 0,
1119 root_metric, visited, table);

--- 11 unchanged lines hidden (view full) ---

1131 ret = __add_metric(metric_list, pe, modifier, metric_no_group, j,
1132 root_metric, visited, table);
1133 }
1134
1135 return ret;
1136}
1137
1138static int metricgroup__add_metric_sys_event_iter(const struct pmu_event *pe,
1139 const struct pmu_event *table __maybe_unused,
1140 void *data)
1139 const struct pmu_events_table *table __maybe_unused,
1140 void *data)
1141{
1142 struct metricgroup_add_iter_data *d = data;
1143 int ret;
1144
1145 if (!match_pe_metric(pe, d->metric_name))
1146 return 0;
1147
1148 ret = add_metric(d->metric_list, pe, d->modifier, d->metric_no_group,

--- 39 unchanged lines hidden (view full) ---

1188 struct list_head *list;
1189 const char *metric_name;
1190 const char *modifier;
1191 bool metric_no_group;
1192 bool has_match;
1193};
1194
1195static int metricgroup__add_metric_callback(const struct pmu_event *pe,
1141{
1142 struct metricgroup_add_iter_data *d = data;
1143 int ret;
1144
1145 if (!match_pe_metric(pe, d->metric_name))
1146 return 0;
1147
1148 ret = add_metric(d->metric_list, pe, d->modifier, d->metric_no_group,

--- 39 unchanged lines hidden (view full) ---

1188 struct list_head *list;
1189 const char *metric_name;
1190 const char *modifier;
1191 bool metric_no_group;
1192 bool has_match;
1193};
1194
1195static int metricgroup__add_metric_callback(const struct pmu_event *pe,
1196 const struct pmu_event *table,
1196 const struct pmu_events_table *table,
1197 void *vdata)
1198{
1199 struct metricgroup__add_metric_data *data = vdata;
1200 int ret = 0;
1201
1202 if (pe->metric_expr &&
1203 (match_metric(pe->metric_group, data->metric_name) ||
1204 match_metric(pe->metric_name, data->metric_name))) {

--- 17 unchanged lines hidden (view full) ---

1222 * user may override.
1223 * @metric_list: The list that the metric or metric group are added to.
1224 * @table: The table that is searched for metrics, most commonly the table for the
1225 * architecture perf is running upon.
1226 */
1227static int metricgroup__add_metric(const char *metric_name, const char *modifier,
1228 bool metric_no_group,
1229 struct list_head *metric_list,
1197 void *vdata)
1198{
1199 struct metricgroup__add_metric_data *data = vdata;
1200 int ret = 0;
1201
1202 if (pe->metric_expr &&
1203 (match_metric(pe->metric_group, data->metric_name) ||
1204 match_metric(pe->metric_name, data->metric_name))) {

--- 17 unchanged lines hidden (view full) ---

1222 * user may override.
1223 * @metric_list: The list that the metric or metric group are added to.
1224 * @table: The table that is searched for metrics, most commonly the table for the
1225 * architecture perf is running upon.
1226 */
1227static int metricgroup__add_metric(const char *metric_name, const char *modifier,
1228 bool metric_no_group,
1229 struct list_head *metric_list,
1230 const struct pmu_event *table)
1230 const struct pmu_events_table *table)
1231{
1232 LIST_HEAD(list);
1233 int ret;
1234 bool has_match = false;
1235
1236 {
1237 struct metricgroup__add_metric_data data = {
1238 .list = &list,

--- 52 unchanged lines hidden (view full) ---

1291 * global. Grouping is the default but due to multiplexing the
1292 * user may override.
1293 * @metric_list: The list that metrics are added to.
1294 * @table: The table that is searched for metrics, most commonly the table for the
1295 * architecture perf is running upon.
1296 */
1297static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
1298 struct list_head *metric_list,
1231{
1232 LIST_HEAD(list);
1233 int ret;
1234 bool has_match = false;
1235
1236 {
1237 struct metricgroup__add_metric_data data = {
1238 .list = &list,

--- 52 unchanged lines hidden (view full) ---

1291 * global. Grouping is the default but due to multiplexing the
1292 * user may override.
1293 * @metric_list: The list that metrics are added to.
1294 * @table: The table that is searched for metrics, most commonly the table for the
1295 * architecture perf is running upon.
1296 */
1297static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
1298 struct list_head *metric_list,
1299 const struct pmu_event *table)
1299 const struct pmu_events_table *table)
1300{
1301 char *list_itr, *list_copy, *metric_name, *modifier;
1302 int ret, count = 0;
1303
1304 list_copy = strdup(list);
1305 if (!list_copy)
1306 return -ENOMEM;
1307 list_itr = list_copy;

--- 191 unchanged lines hidden (view full) ---

1499 return ret;
1500}
1501
1502static int parse_groups(struct evlist *perf_evlist, const char *str,
1503 bool metric_no_group,
1504 bool metric_no_merge,
1505 struct perf_pmu *fake_pmu,
1506 struct rblist *metric_events_list,
1300{
1301 char *list_itr, *list_copy, *metric_name, *modifier;
1302 int ret, count = 0;
1303
1304 list_copy = strdup(list);
1305 if (!list_copy)
1306 return -ENOMEM;
1307 list_itr = list_copy;

--- 191 unchanged lines hidden (view full) ---

1499 return ret;
1500}
1501
1502static int parse_groups(struct evlist *perf_evlist, const char *str,
1503 bool metric_no_group,
1504 bool metric_no_merge,
1505 struct perf_pmu *fake_pmu,
1506 struct rblist *metric_events_list,
1507 const struct pmu_event *table)
1507 const struct pmu_events_table *table)
1508{
1509 struct evlist *combined_evlist = NULL;
1510 LIST_HEAD(metric_list);
1511 struct metric *m;
1512 bool tool_events[PERF_TOOL_MAX] = {false};
1513 int ret;
1514
1515 if (metric_events_list->nr_entries == 0)

--- 129 unchanged lines hidden (view full) ---

1645
1646int metricgroup__parse_groups(const struct option *opt,
1647 const char *str,
1648 bool metric_no_group,
1649 bool metric_no_merge,
1650 struct rblist *metric_events)
1651{
1652 struct evlist *perf_evlist = *(struct evlist **)opt->value;
1508{
1509 struct evlist *combined_evlist = NULL;
1510 LIST_HEAD(metric_list);
1511 struct metric *m;
1512 bool tool_events[PERF_TOOL_MAX] = {false};
1513 int ret;
1514
1515 if (metric_events_list->nr_entries == 0)

--- 129 unchanged lines hidden (view full) ---

1645
1646int metricgroup__parse_groups(const struct option *opt,
1647 const char *str,
1648 bool metric_no_group,
1649 bool metric_no_merge,
1650 struct rblist *metric_events)
1651{
1652 struct evlist *perf_evlist = *(struct evlist **)opt->value;
1653 const struct pmu_event *table = pmu_events_table__find();
1653 const struct pmu_events_table *table = pmu_events_table__find();
1654
1655 return parse_groups(perf_evlist, str, metric_no_group,
1656 metric_no_merge, NULL, metric_events, table);
1657}
1658
1659int metricgroup__parse_groups_test(struct evlist *evlist,
1654
1655 return parse_groups(perf_evlist, str, metric_no_group,
1656 metric_no_merge, NULL, metric_events, table);
1657}
1658
1659int metricgroup__parse_groups_test(struct evlist *evlist,
1660 const struct pmu_event *table,
1660 const struct pmu_events_table *table,
1661 const char *str,
1662 bool metric_no_group,
1663 bool metric_no_merge,
1664 struct rblist *metric_events)
1665{
1666 return parse_groups(evlist, str, metric_no_group,
1667 metric_no_merge, &perf_pmu__fake, metric_events, table);
1668}
1669
1670static int metricgroup__has_metric_callback(const struct pmu_event *pe,
1661 const char *str,
1662 bool metric_no_group,
1663 bool metric_no_merge,
1664 struct rblist *metric_events)
1665{
1666 return parse_groups(evlist, str, metric_no_group,
1667 metric_no_merge, &perf_pmu__fake, metric_events, table);
1668}
1669
1670static int metricgroup__has_metric_callback(const struct pmu_event *pe,
1671 const struct pmu_event *table __maybe_unused,
1671 const struct pmu_events_table *table __maybe_unused,
1672 void *vdata)
1673{
1674 const char *metric = vdata;
1675
1676 if (!pe->metric_expr)
1677 return 0;
1678
1679 if (match_metric(pe->metric_name, metric))
1680 return 1;
1681
1682 return 0;
1683}
1684
1685bool metricgroup__has_metric(const char *metric)
1686{
1672 void *vdata)
1673{
1674 const char *metric = vdata;
1675
1676 if (!pe->metric_expr)
1677 return 0;
1678
1679 if (match_metric(pe->metric_name, metric))
1680 return 1;
1681
1682 return 0;
1683}
1684
1685bool metricgroup__has_metric(const char *metric)
1686{
1687 const struct pmu_event *table = pmu_events_table__find();
1687 const struct pmu_events_table *table = pmu_events_table__find();
1688
1689 if (!table)
1690 return false;
1691
1692 return pmu_events_table_for_each_event(table, metricgroup__has_metric_callback,
1693 (void *)metric) ? true : false;
1694}
1695

--- 86 unchanged lines hidden ---
1688
1689 if (!table)
1690 return false;
1691
1692 return pmu_events_table_for_each_event(table, metricgroup__has_metric_callback,
1693 (void *)metric) ? true : false;
1694}
1695

--- 86 unchanged lines hidden ---