On 7/19/20 11:43 PM, Jiri Olsa wrote: > Add referenced metrics into struct metric_expr object, > so they are accessible when computing the metric. > > Storing just name and expression itself, so the metric > can be resolved and computed. > > Acked-by: Ian Rogers <irog...@google.com> > Signed-off-by: Jiri Olsa <jo...@kernel.org> Reviewed-By : Kajol Jain<kj...@linux.ibm.com> Thanks, Kajol Jain > --- > tools/perf/util/metricgroup.c | 32 ++++++++++++++++++++++++++++++++ > tools/perf/util/metricgroup.h | 6 ++++++ > 2 files changed, 38 insertions(+) > > diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c > index d1b2c1aa436f..bb5757b9419d 100644 > --- a/tools/perf/util/metricgroup.c > +++ b/tools/perf/util/metricgroup.c > @@ -83,6 +83,7 @@ static void metric_event_delete(struct rblist *rblist > __maybe_unused, > struct metric_expr *expr, *tmp; > > list_for_each_entry_safe(expr, tmp, &me->head, nd) { > + free(expr->metric_refs); > free(expr); > } > > @@ -248,6 +249,7 @@ static int metricgroup__setup_events(struct list_head > *groups, > > list_for_each_entry (eg, groups, nd) { > struct evsel **metric_events; > + struct metric_ref *metric_refs = NULL; > > metric_events = calloc(sizeof(void *), > hashmap__size(&eg->pctx.ids) + 1); > @@ -279,6 +281,36 @@ static int metricgroup__setup_events(struct list_head > *groups, > free(metric_events); > break; > } > + > + /* > + * Collect and store collected nested expressions > + * for metric processing. > + */ > + if (eg->metric_refs_cnt) { > + struct metric_ref_node *ref; > + > + metric_refs = zalloc(sizeof(struct metric_ref) * > (eg->metric_refs_cnt + 1)); > + if (!metric_refs) { > + ret = -ENOMEM; > + free(metric_events); > + break; > + } > + > + i = 0; > + list_for_each_entry(ref, &eg->metric_refs, list) { > + /* > + * Intentionally passing just const char > pointers, > + * originally from 'struct pmu_event' object. > + * We don't need to change them, so there's no > + * need to create our own copy. > + */ > + metric_refs[i].metric_name = ref->metric_name; > + metric_refs[i].metric_expr = ref->metric_expr; > + i++; > + } > + }; > + > + expr->metric_refs = metric_refs; > expr->metric_expr = eg->metric_expr; > expr->metric_name = eg->metric_name; > expr->metric_unit = eg->metric_unit; > diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h > index 8315bd1a7da4..62623a39cbec 100644 > --- a/tools/perf/util/metricgroup.h > +++ b/tools/perf/util/metricgroup.h > @@ -18,12 +18,18 @@ struct metric_event { > struct list_head head; /* list of metric_expr */ > }; > > +struct metric_ref { > + const char *metric_name; > + const char *metric_expr; > +}; > + > struct metric_expr { > struct list_head nd; > const char *metric_expr; > const char *metric_name; > const char *metric_unit; > struct evsel **metric_events; > + struct metric_ref *metric_refs; > int runtime; > }; > >