Skip to content

Commit cb336b6

Browse files
captain5050namhyung
authored andcommitted
perf metricgroup: Factor out for-each function and move out printing
Factor metricgroup__for_each_metric into its own function handling regular and sys metrics. Make the metric adding and printing code use it, move the printing code into print-events files. Signed-off-by: Ian Rogers <irogers@google.com> Link: https://lore.kernel.org/r/20250710235126.1086011-6-irogers@google.com Signed-off-by: Namhyung Kim <namhyung@kernel.org>
1 parent 8c75dc7 commit cb336b6

File tree

4 files changed

+165
-214
lines changed

4 files changed

+165
-214
lines changed

tools/perf/util/metricgroup.c

Lines changed: 28 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -384,107 +384,6 @@ static bool match_pm_metric_or_groups(const struct pmu_metric *pm, const char *p
384384
match_metric_or_groups(pm->metric_name, metric_or_groups);
385385
}
386386

387-
/** struct mep - RB-tree node for building printing information. */
388-
struct mep {
389-
/** nd - RB-tree element. */
390-
struct rb_node nd;
391-
/** @metric_group: Owned metric group name, separated others with ';'. */
392-
char *metric_group;
393-
const char *metric_name;
394-
const char *metric_desc;
395-
const char *metric_long_desc;
396-
const char *metric_expr;
397-
const char *metric_threshold;
398-
const char *metric_unit;
399-
const char *pmu_name;
400-
};
401-
402-
static int mep_cmp(struct rb_node *rb_node, const void *entry)
403-
{
404-
struct mep *a = container_of(rb_node, struct mep, nd);
405-
struct mep *b = (struct mep *)entry;
406-
int ret;
407-
408-
ret = strcmp(a->metric_group, b->metric_group);
409-
if (ret)
410-
return ret;
411-
412-
return strcmp(a->metric_name, b->metric_name);
413-
}
414-
415-
static struct rb_node *mep_new(struct rblist *rl __maybe_unused, const void *entry)
416-
{
417-
struct mep *me = malloc(sizeof(struct mep));
418-
419-
if (!me)
420-
return NULL;
421-
422-
memcpy(me, entry, sizeof(struct mep));
423-
return &me->nd;
424-
}
425-
426-
static void mep_delete(struct rblist *rl __maybe_unused,
427-
struct rb_node *nd)
428-
{
429-
struct mep *me = container_of(nd, struct mep, nd);
430-
431-
zfree(&me->metric_group);
432-
free(me);
433-
}
434-
435-
static struct mep *mep_lookup(struct rblist *groups, const char *metric_group,
436-
const char *metric_name)
437-
{
438-
struct rb_node *nd;
439-
struct mep me = {
440-
.metric_group = strdup(metric_group),
441-
.metric_name = metric_name,
442-
};
443-
nd = rblist__find(groups, &me);
444-
if (nd) {
445-
free(me.metric_group);
446-
return container_of(nd, struct mep, nd);
447-
}
448-
rblist__add_node(groups, &me);
449-
nd = rblist__find(groups, &me);
450-
if (nd)
451-
return container_of(nd, struct mep, nd);
452-
return NULL;
453-
}
454-
455-
static int metricgroup__add_to_mep_groups(const struct pmu_metric *pm,
456-
struct rblist *groups)
457-
{
458-
const char *g;
459-
char *omg, *mg;
460-
461-
mg = strdup(pm->metric_group ?: pm->metric_name);
462-
if (!mg)
463-
return -ENOMEM;
464-
omg = mg;
465-
while ((g = strsep(&mg, ";")) != NULL) {
466-
struct mep *me;
467-
468-
g = skip_spaces(g);
469-
if (strlen(g))
470-
me = mep_lookup(groups, g, pm->metric_name);
471-
else
472-
me = mep_lookup(groups, pm->metric_name, pm->metric_name);
473-
474-
if (me) {
475-
me->metric_desc = pm->desc;
476-
me->metric_long_desc = pm->long_desc;
477-
me->metric_expr = pm->metric_expr;
478-
me->metric_threshold = pm->metric_threshold;
479-
me->metric_unit = pm->unit;
480-
me->pmu_name = pm->pmu;
481-
}
482-
}
483-
free(omg);
484-
485-
return 0;
486-
}
487-
488387
struct metricgroup_iter_data {
489388
pmu_metric_iter_fn fn;
490389
void *data;
@@ -510,54 +409,22 @@ static int metricgroup__sys_event_iter(const struct pmu_metric *pm,
510409
return 0;
511410
}
512411

513-
static int metricgroup__add_to_mep_groups_callback(const struct pmu_metric *pm,
514-
const struct pmu_metrics_table *table __maybe_unused,
515-
void *vdata)
412+
int metricgroup__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn,
413+
void *data)
516414
{
517-
struct rblist *groups = vdata;
518-
519-
return metricgroup__add_to_mep_groups(pm, groups);
520-
}
521-
522-
void metricgroup__print(const struct print_callbacks *print_cb, void *print_state)
523-
{
524-
struct rblist groups;
525-
const struct pmu_metrics_table *table;
526-
struct rb_node *node, *next;
415+
struct metricgroup_iter_data sys_data = {
416+
.fn = fn,
417+
.data = data,
418+
};
527419

528-
rblist__init(&groups);
529-
groups.node_new = mep_new;
530-
groups.node_cmp = mep_cmp;
531-
groups.node_delete = mep_delete;
532-
table = pmu_metrics_table__find();
533420
if (table) {
534-
pmu_metrics_table__for_each_metric(table,
535-
metricgroup__add_to_mep_groups_callback,
536-
&groups);
537-
}
538-
{
539-
struct metricgroup_iter_data data = {
540-
.fn = metricgroup__add_to_mep_groups_callback,
541-
.data = &groups,
542-
};
543-
pmu_for_each_sys_metric(metricgroup__sys_event_iter, &data);
544-
}
421+
int ret = pmu_metrics_table__for_each_metric(table, fn, data);
545422

546-
for (node = rb_first_cached(&groups.entries); node; node = next) {
547-
struct mep *me = container_of(node, struct mep, nd);
548-
549-
print_cb->print_metric(print_state,
550-
me->metric_group,
551-
me->metric_name,
552-
me->metric_desc,
553-
me->metric_long_desc,
554-
me->metric_expr,
555-
me->metric_threshold,
556-
me->metric_unit,
557-
me->pmu_name);
558-
next = rb_next(node);
559-
rblist__remove_node(&groups, node);
423+
if (ret)
424+
return ret;
560425
}
426+
427+
return pmu_for_each_sys_metric(metricgroup__sys_event_iter, &sys_data);
561428
}
562429

563430
static const char *code_characters = ",-=@";
@@ -1090,29 +957,6 @@ static int add_metric(struct list_head *metric_list,
1090957
return ret;
1091958
}
1092959

1093-
static int metricgroup__add_metric_sys_event_iter(const struct pmu_metric *pm,
1094-
const struct pmu_metrics_table *table __maybe_unused,
1095-
void *data)
1096-
{
1097-
struct metricgroup_add_iter_data *d = data;
1098-
int ret;
1099-
1100-
if (!match_pm_metric_or_groups(pm, d->pmu, d->metric_name))
1101-
return 0;
1102-
1103-
ret = add_metric(d->metric_list, pm, d->modifier, d->metric_no_group,
1104-
d->metric_no_threshold, d->user_requested_cpu_list,
1105-
d->system_wide, d->root_metric, d->visited, d->table);
1106-
if (ret)
1107-
goto out;
1108-
1109-
*(d->has_match) = true;
1110-
1111-
out:
1112-
*(d->ret) = ret;
1113-
return ret;
1114-
}
1115-
1116960
/**
1117961
* metric_list_cmp - list_sort comparator that sorts metrics with more events to
1118962
* the front. tool events are excluded from the count.
@@ -1216,55 +1060,26 @@ static int metricgroup__add_metric(const char *pmu, const char *metric_name, con
12161060
{
12171061
LIST_HEAD(list);
12181062
int ret;
1219-
bool has_match = false;
1220-
1221-
{
1222-
struct metricgroup__add_metric_data data = {
1223-
.list = &list,
1224-
.pmu = pmu,
1225-
.metric_name = metric_name,
1226-
.modifier = modifier,
1227-
.metric_no_group = metric_no_group,
1228-
.metric_no_threshold = metric_no_threshold,
1229-
.user_requested_cpu_list = user_requested_cpu_list,
1230-
.system_wide = system_wide,
1231-
.has_match = false,
1232-
};
1233-
/*
1234-
* Iterate over all metrics seeing if metric matches either the
1235-
* name or group. When it does add the metric to the list.
1236-
*/
1237-
ret = pmu_metrics_table__for_each_metric(table, metricgroup__add_metric_callback,
1238-
&data);
1239-
if (ret)
1240-
goto out;
1063+
struct metricgroup__add_metric_data data = {
1064+
.list = &list,
1065+
.pmu = pmu,
1066+
.metric_name = metric_name,
1067+
.modifier = modifier,
1068+
.metric_no_group = metric_no_group,
1069+
.metric_no_threshold = metric_no_threshold,
1070+
.user_requested_cpu_list = user_requested_cpu_list,
1071+
.system_wide = system_wide,
1072+
.has_match = false,
1073+
};
12411074

1242-
has_match = data.has_match;
1243-
}
1244-
{
1245-
struct metricgroup_iter_data data = {
1246-
.fn = metricgroup__add_metric_sys_event_iter,
1247-
.data = (void *) &(struct metricgroup_add_iter_data) {
1248-
.metric_list = &list,
1249-
.pmu = pmu,
1250-
.metric_name = metric_name,
1251-
.modifier = modifier,
1252-
.metric_no_group = metric_no_group,
1253-
.user_requested_cpu_list = user_requested_cpu_list,
1254-
.system_wide = system_wide,
1255-
.has_match = &has_match,
1256-
.ret = &ret,
1257-
.table = table,
1258-
},
1259-
};
1260-
1261-
pmu_for_each_sys_metric(metricgroup__sys_event_iter, &data);
1262-
}
1263-
/* End of pmu events. */
1264-
if (!has_match)
1075+
/*
1076+
* Iterate over all metrics seeing if metric matches either the
1077+
* name or group. When it does add the metric to the list.
1078+
*/
1079+
ret = metricgroup__for_each_metric(table, metricgroup__add_metric_callback, &data);
1080+
if (!ret && !data.has_match)
12651081
ret = -EINVAL;
12661082

1267-
out:
12681083
/*
12691084
* add to metric_list so that they can be released
12701085
* even if it's failed

tools/perf/util/metricgroup.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ int metricgroup__parse_groups_test(struct evlist *evlist,
8484
const char *str,
8585
struct rblist *metric_events);
8686

87-
void metricgroup__print(const struct print_callbacks *print_cb, void *print_state);
87+
int metricgroup__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn,
88+
void *data);
8889
bool metricgroup__has_metric_or_groups(const char *pmu, const char *metric_or_groups);
8990
unsigned int metricgroups__topdown_max_level(void);
9091
int arch_get_runtimeparam(const struct pmu_metric *pm);

0 commit comments

Comments
 (0)