perf metric: Simplify metric_refs calculation
authorIan Rogers <irogers@google.com>
Fri, 15 Oct 2021 17:21:23 +0000 (10:21 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 20 Oct 2021 13:41:06 +0000 (10:41 -0300)
Don't build a list and then turn to an array, just directly build the
array.

The size of the array is known due to the search for a duplicate.

Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Antonov <alexander.antonov@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andrew Kilroy <andrew.kilroy@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Changbin Du <changbin.du@intel.com>
Cc: Denys Zagorui <dzagorui@cisco.com>
Cc: Fabian Hemmer <copy@copy.sh>
Cc: Felix Fietkau <nbd@nbd.name>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jacob Keller <jacob.e.keller@intel.com>
Cc: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
Cc: Jin Yao <yao.jin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Kees Kook <keescook@chromium.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nicholas Fraser <nfraser@codeweavers.com>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Paul Clarke <pc@us.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: ShihCheng Tu <mrtoastcheng@gmail.com>
Cc: Song Liu <songliubraving@fb.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Wan Jiabing <wanjiabing@vivo.com>
Cc: Zhen Lei <thunder.leizhen@huawei.com>
Link: https://lore.kernel.org/r/20211015172132.1162559-13-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/metricgroup.c

index 632867c..b48836d 100644 (file)
@@ -137,10 +137,8 @@ struct metric {
         * output.
         */
        const char *metric_unit;
-       /** The list of metrics referenced by this one. */
-       struct list_head metric_refs;
-       /** The size of the metric_refs list. */
-       int metric_refs_cnt;
+       /** Optional null terminated array of referenced metrics. */
+       struct metric_ref *metric_refs;
        /**
         * Is there a constraint on the group of events? In which case the
         * events won't be grouped.
@@ -202,20 +200,14 @@ static struct metric *metric__new(const struct pmu_event *pe,
        m->metric_unit = pe->unit;
        m->pctx->runtime = runtime;
        m->has_constraint = metric_no_group || metricgroup__has_constraint(pe);
-       INIT_LIST_HEAD(&m->metric_refs);
-       m->metric_refs_cnt = 0;
+       m->metric_refs = NULL;
 
        return m;
 }
 
 static void metric__free(struct metric *m)
 {
-       struct metric_ref_node *ref, *tmp;
-
-       list_for_each_entry_safe(ref, tmp, &m->metric_refs, list) {
-               list_del(&ref->list);
-               free(ref);
-       }
+       free(m->metric_refs);
        expr__ctx_free(m->pctx);
        free(m);
 }
@@ -393,7 +385,6 @@ static int metricgroup__setup_events(struct list_head *groups,
 
        list_for_each_entry (m, groups, nd) {
                struct evsel **metric_events;
-               struct metric_ref *metric_refs = NULL;
                const size_t ids_size = hashmap__size(m->pctx->ids);
 
                metric_events = calloc(sizeof(void *),
@@ -427,36 +418,8 @@ static int metricgroup__setup_events(struct list_head *groups,
                        break;
                }
 
-               /*
-                * Collect and store collected nested expressions
-                * for metric processing.
-                */
-               if (m->metric_refs_cnt) {
-                       struct metric_ref_node *ref;
-
-                       metric_refs = zalloc(sizeof(struct metric_ref) * (m->metric_refs_cnt + 1));
-                       if (!metric_refs) {
-                               ret = -ENOMEM;
-                               free(metric_events);
-                               free(expr);
-                               break;
-                       }
-
-                       i = 0;
-                       list_for_each_entry(ref, &m->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_refs = m->metric_refs;
+               m->metric_refs = NULL;
                expr->metric_expr = m->metric_expr;
                expr->metric_name = m->metric_name;
                expr->metric_unit = m->metric_unit;
@@ -936,7 +899,6 @@ static int __add_metric(struct list_head *metric_list,
                        const struct visited_metric *visited,
                        const struct pmu_events_map *map)
 {
-       struct metric_ref_node *ref;
        const struct visited_metric *vm;
        int ret;
        bool is_root = !root_metric;
@@ -962,19 +924,25 @@ static int __add_metric(struct list_head *metric_list,
                        return -ENOMEM;
 
        } else {
+               int cnt = 0;
+
                /*
                 * This metric was referenced in a metric higher in the
                 * tree. Check if the same metric is already resolved in the
                 * metric_refs list.
                 */
-               list_for_each_entry(ref, &root_metric->metric_refs, list) {
-                       if (!strcmp(pe->metric_name, ref->metric_name))
-                               return 0;
+               if (root_metric->metric_refs) {
+                       for (; root_metric->metric_refs[cnt].metric_name; cnt++) {
+                               if (!strcmp(pe->metric_name,
+                                           root_metric->metric_refs[cnt].metric_name))
+                                       return 0;
+                       }
                }
 
-               /* Create reference */
-               ref = malloc(sizeof(*ref));
-               if (!ref)
+               /* Create reference. Need space for the entry and the terminator. */
+               root_metric->metric_refs = realloc(root_metric->metric_refs,
+                                               (cnt + 2) * sizeof(struct metric_ref));
+               if (!root_metric->metric_refs)
                        return -ENOMEM;
 
                /*
@@ -983,11 +951,12 @@ static int __add_metric(struct list_head *metric_list,
                 * need to change them, so there's no need to create
                 * our own copy.
                 */
-               ref->metric_name = pe->metric_name;
-               ref->metric_expr = pe->metric_expr;
+               root_metric->metric_refs[cnt].metric_name = pe->metric_name;
+               root_metric->metric_refs[cnt].metric_expr = pe->metric_expr;
 
-               list_add(&ref->list, &root_metric->metric_refs);
-               root_metric->metric_refs_cnt++;
+               /* Null terminate array. */
+               root_metric->metric_refs[cnt+1].metric_name = NULL;
+               root_metric->metric_refs[cnt+1].metric_expr = NULL;
        }
 
        /*