OSDN Git Service

perf stat: Allocate evsel->stats->aggr properly
authorNamhyung Kim <namhyung@kernel.org>
Tue, 18 Oct 2022 02:02:15 +0000 (19:02 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 27 Oct 2022 19:37:25 +0000 (16:37 -0300)
The perf_stat_config.aggr_map should have a correct size of the
aggregation map.  Use it to allocate aggr_counts.

Also AGGR_NONE with per-core events can be tricky because it doesn't
aggreate basically but it needs to do so for per-core events only.
So only per-core evsels will have stats->aggr data.

Note that other caller of evlist__alloc_stat() might not have
stat_config or aggr_map.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Link: https://lore.kernel.org/r/20221018020227.85905-9-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-script.c
tools/perf/builtin-stat.c
tools/perf/tests/parse-metric.c
tools/perf/tests/pmu-events.c
tools/perf/util/stat.c
tools/perf/util/stat.h

index 7ca2382..d7ec8c1 100644 (file)
@@ -2049,7 +2049,7 @@ static void perf_sample__fprint_metric(struct perf_script *script,
        u64 val;
 
        if (!evsel->stats)
-               evlist__alloc_stats(script->session->evlist, false);
+               evlist__alloc_stats(&stat_config, script->session->evlist, /*alloc_raw=*/false);
        if (evsel_script(leader)->gnum++ == 0)
                perf_stat__reset_shadow_stats();
        val = sample->period * evsel->scale;
@@ -3632,7 +3632,7 @@ static int set_maps(struct perf_script *script)
 
        perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);
 
-       if (evlist__alloc_stats(evlist, true))
+       if (evlist__alloc_stats(&stat_config, evlist, /*alloc_raw=*/true))
                return -ENOMEM;
 
        script->allocated = true;
index 9053fd4..92a8e45 100644 (file)
@@ -2121,7 +2121,7 @@ static int set_maps(struct perf_stat *st)
 
        perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads);
 
-       if (evlist__alloc_stats(evsel_list, true))
+       if (evlist__alloc_stats(&stat_config, evsel_list, /*alloc_raw=*/true))
                return -ENOMEM;
 
        st->maps_allocated = true;
@@ -2568,10 +2568,10 @@ int cmd_stat(int argc, const char **argv)
                goto out;
        }
 
-       if (evlist__alloc_stats(evsel_list, interval))
+       if (perf_stat_init_aggr_mode())
                goto out;
 
-       if (perf_stat_init_aggr_mode())
+       if (evlist__alloc_stats(&stat_config, evsel_list, interval))
                goto out;
 
        /*
index 68f5a2a..21b7ac0 100644 (file)
@@ -103,7 +103,7 @@ static int __compute_metric(const char *name, struct value *vals,
        if (err)
                goto out;
 
-       err = evlist__alloc_stats(evlist, false);
+       err = evlist__alloc_stats(/*config=*/NULL, evlist, /*alloc_raw=*/false);
        if (err)
                goto out;
 
index 097e05c..5d0d3b2 100644 (file)
@@ -889,7 +889,7 @@ static int test__parsing_callback(const struct pmu_event *pe, const struct pmu_e
                goto out_err;
        }
 
-       err = evlist__alloc_stats(evlist, false);
+       err = evlist__alloc_stats(/*config=*/NULL, evlist, /*alloc_raw=*/false);
        if (err)
                goto out_err;
        /*
index c9d5aa2..3741496 100644 (file)
@@ -211,12 +211,17 @@ static int evsel__alloc_stats(struct evsel *evsel, int nr_aggr, bool alloc_raw)
        return 0;
 }
 
-int evlist__alloc_stats(struct evlist *evlist, bool alloc_raw)
+int evlist__alloc_stats(struct perf_stat_config *config,
+                       struct evlist *evlist, bool alloc_raw)
 {
        struct evsel *evsel;
+       int nr_aggr = 0;
+
+       if (config && config->aggr_map)
+               nr_aggr = config->aggr_map->nr;
 
        evlist__for_each_entry(evlist, evsel) {
-               if (evsel__alloc_stats(evsel, 0, alloc_raw))
+               if (evsel__alloc_stats(evsel, nr_aggr, alloc_raw))
                        goto out_free;
        }
 
index 4245351..0980875 100644 (file)
@@ -267,7 +267,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
                                   struct runtime_stat *st);
 void perf_stat__collect_metric_expr(struct evlist *);
 
-int evlist__alloc_stats(struct evlist *evlist, bool alloc_raw);
+int evlist__alloc_stats(struct perf_stat_config *config,
+                       struct evlist *evlist, bool alloc_raw);
 void evlist__free_stats(struct evlist *evlist);
 void evlist__reset_stats(struct evlist *evlist);
 void evlist__reset_prev_raw_counts(struct evlist *evlist);