OSDN Git Service

perf stat: Allocate aggr counts for recorded data
authorNamhyung Kim <namhyung@kernel.org>
Tue, 18 Oct 2022 02:02:19 +0000 (19:02 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 27 Oct 2022 19:37:25 +0000 (16:37 -0300)
In the process_stat_config_event() it sets the aggr_mode that means the
earlier evlist__alloc_stats() cannot allocate the aggr counts due to the
missing aggr_mode.

Do it after setting the aggr_map using evlist__alloc_aggr_stats().

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-13-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-stat.c
tools/perf/util/stat.c
tools/perf/util/stat.h

index 6777fef..2a6a5d0 100644 (file)
@@ -1342,7 +1342,11 @@ static struct aggr_cpu_id perf_stat__get_cpu(struct perf_stat_config *config __m
 static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config,
                                              aggr_get_id_t get_id, struct perf_cpu cpu)
 {
-       struct aggr_cpu_id id = aggr_cpu_id__empty();
+       struct aggr_cpu_id id;
+
+       /* per-process mode - should use global aggr mode */
+       if (cpu.cpu == -1)
+               return get_id(config, cpu);
 
        if (aggr_cpu_id__is_empty(&config->cpus_aggr_map->map[cpu.cpu]))
                config->cpus_aggr_map->map[cpu.cpu] = get_id(config, cpu);
@@ -2125,17 +2129,23 @@ int process_stat_config_event(struct perf_session *session,
        if (perf_cpu_map__empty(st->cpus)) {
                if (st->aggr_mode != AGGR_UNSET)
                        pr_warning("warning: processing task data, aggregation mode not set\n");
-               return 0;
-       }
-
-       if (st->aggr_mode != AGGR_UNSET)
+       } else if (st->aggr_mode != AGGR_UNSET) {
                stat_config.aggr_mode = st->aggr_mode;
+       }
 
        if (perf_stat.data.is_pipe)
                perf_stat_init_aggr_mode();
        else
                perf_stat_init_aggr_mode_file(st);
 
+       if (stat_config.aggr_map) {
+               int nr_aggr = stat_config.aggr_map->nr;
+
+               if (evlist__alloc_aggr_stats(session->evlist, nr_aggr) < 0) {
+                       pr_err("cannot allocate aggr counts\n");
+                       return -1;
+               }
+       }
        return 0;
 }
 
index 5b04c9d..1b90481 100644 (file)
@@ -141,6 +141,31 @@ static void evsel__reset_stat_priv(struct evsel *evsel)
                memset(aggr, 0, sizeof(*aggr) * ps->nr_aggr);
 }
 
+static int evsel__alloc_aggr_stats(struct evsel *evsel, int nr_aggr)
+{
+       struct perf_stat_evsel *ps = evsel->stats;
+
+       if (ps == NULL)
+               return 0;
+
+       ps->nr_aggr = nr_aggr;
+       ps->aggr = calloc(nr_aggr, sizeof(*ps->aggr));
+       if (ps->aggr == NULL)
+               return -ENOMEM;
+
+       return 0;
+}
+
+int evlist__alloc_aggr_stats(struct evlist *evlist, int nr_aggr)
+{
+       struct evsel *evsel;
+
+       evlist__for_each_entry(evlist, evsel) {
+               if (evsel__alloc_aggr_stats(evsel, nr_aggr) < 0)
+                       return -1;
+       }
+       return 0;
+}
 
 static int evsel__alloc_stat_priv(struct evsel *evsel, int nr_aggr)
 {
@@ -150,16 +175,14 @@ static int evsel__alloc_stat_priv(struct evsel *evsel, int nr_aggr)
        if (ps == NULL)
                return -ENOMEM;
 
-       if (nr_aggr) {
-               ps->nr_aggr = nr_aggr;
-               ps->aggr = calloc(nr_aggr, sizeof(*ps->aggr));
-               if (ps->aggr == NULL) {
-                       free(ps);
-                       return -ENOMEM;
-               }
+       evsel->stats = ps;
+
+       if (nr_aggr && evsel__alloc_aggr_stats(evsel, nr_aggr) < 0) {
+               evsel->stats = NULL;
+               free(ps);
+               return -ENOMEM;
        }
 
-       evsel->stats = ps;
        perf_stat_evsel_id_init(evsel);
        evsel__reset_stat_priv(evsel);
        return 0;
index 0980875..4c00f81 100644 (file)
@@ -275,6 +275,8 @@ void evlist__reset_prev_raw_counts(struct evlist *evlist);
 void evlist__copy_prev_raw_counts(struct evlist *evlist);
 void evlist__save_aggr_prev_raw_counts(struct evlist *evlist);
 
+int evlist__alloc_aggr_stats(struct evlist *evlist, int nr_aggr);
+
 int perf_stat_process_counter(struct perf_stat_config *config,
                              struct evsel *counter);
 struct perf_tool;