perf stat: Add struct perf_stat_aggr to perf_stat_evsel
authorNamhyung Kim <namhyung@kernel.org>
Tue, 18 Oct 2022 02:02:14 +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_aggr struct is to keep aggregated counter values and the
states according to the aggregation mode.  The number of entries is
depends on the mode and this is a preparation for the later use.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ian Rogers <irogers@google.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-8-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/stat.c
tools/perf/util/stat.h

index 8ec8bb4a99129b19176cae155e0ff9e5dd6e900d..c9d5aa295b54141aeb441f3d036f191b4b73918f 100644 (file)
@@ -133,15 +133,33 @@ static void perf_stat_evsel_id_init(struct evsel *evsel)
 static void evsel__reset_stat_priv(struct evsel *evsel)
 {
        struct perf_stat_evsel *ps = evsel->stats;
+       struct perf_stat_aggr *aggr = ps->aggr;
 
        init_stats(&ps->res_stats);
+
+       if (aggr)
+               memset(aggr, 0, sizeof(*aggr) * ps->nr_aggr);
 }
 
-static int evsel__alloc_stat_priv(struct evsel *evsel)
+
+static int evsel__alloc_stat_priv(struct evsel *evsel, int nr_aggr)
 {
-       evsel->stats = zalloc(sizeof(struct perf_stat_evsel));
-       if (evsel->stats == NULL)
+       struct perf_stat_evsel *ps;
+
+       ps = zalloc(sizeof(*ps));
+       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;
        perf_stat_evsel_id_init(evsel);
        evsel__reset_stat_priv(evsel);
        return 0;
@@ -151,8 +169,10 @@ static void evsel__free_stat_priv(struct evsel *evsel)
 {
        struct perf_stat_evsel *ps = evsel->stats;
 
-       if (ps)
+       if (ps) {
+               zfree(&ps->aggr);
                zfree(&ps->group_data);
+       }
        zfree(&evsel->stats);
 }
 
@@ -181,9 +201,9 @@ static void evsel__reset_prev_raw_counts(struct evsel *evsel)
                perf_counts__reset(evsel->prev_raw_counts);
 }
 
-static int evsel__alloc_stats(struct evsel *evsel, bool alloc_raw)
+static int evsel__alloc_stats(struct evsel *evsel, int nr_aggr, bool alloc_raw)
 {
-       if (evsel__alloc_stat_priv(evsel) < 0 ||
+       if (evsel__alloc_stat_priv(evsel, nr_aggr) < 0 ||
            evsel__alloc_counts(evsel) < 0 ||
            (alloc_raw && evsel__alloc_prev_raw_counts(evsel) < 0))
                return -ENOMEM;
@@ -196,7 +216,7 @@ int evlist__alloc_stats(struct evlist *evlist, bool alloc_raw)
        struct evsel *evsel;
 
        evlist__for_each_entry(evlist, evsel) {
-               if (evsel__alloc_stats(evsel, alloc_raw))
+               if (evsel__alloc_stats(evsel, 0, alloc_raw))
                        goto out_free;
        }
 
index b0899c6e002f50bf18368489b35258028d54c786..42453513ffea8b426dca78c747da93e955e1a339 100644 (file)
@@ -8,6 +8,7 @@
 #include <sys/resource.h>
 #include "cpumap.h"
 #include "rblist.h"
+#include "counts.h"
 
 struct perf_cpu_map;
 struct perf_stat_config;
@@ -42,9 +43,27 @@ enum perf_stat_evsel_id {
        PERF_STAT_EVSEL_ID__MAX,
 };
 
+/* hold aggregated event info */
+struct perf_stat_aggr {
+       /* aggregated values */
+       struct perf_counts_values       counts;
+       /* number of entries (CPUs) aggregated */
+       int                             nr;
+       /* whether any entry has failed to read/process event */
+       bool                            failed;
+};
+
+/* per-evsel event stats */
 struct perf_stat_evsel {
+       /* used for repeated runs */
        struct stats             res_stats;
+       /* evsel id for quick check */
        enum perf_stat_evsel_id  id;
+       /* number of allocated 'aggr' */
+       int                      nr_aggr;
+       /* aggregated event values */
+       struct perf_stat_aggr   *aggr;
+       /* used for group read */
        u64                     *group_data;
 };