Currently any time we need to access socket or core id for
given cpu, we access the sysfs topology file.

Adding cpus_aggr_map cpu_map to cache those entries.

Link: http://lkml.kernel.org/n/tip-2cw82b5piydhao8sft09a...@git.kernel.org
Signed-off-by: Jiri Olsa <jo...@kernel.org>
---
 tools/perf/builtin-stat.c | 60 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 56 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 9e51e662c318..a6d73d84edf1 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -101,6 +101,8 @@ static struct target target = {
        .uid    = UINT_MAX,
 };
 
+typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);
+
 static int                     run_count                       =  1;
 static bool                    no_inherit                      = false;
 static volatile pid_t          child_pid                       = -1;
@@ -120,7 +122,7 @@ static unsigned int         unit_width                      
= 4; /* strlen("unit") */
 static bool                    forever                         = false;
 static struct timespec         ref_time;
 static struct cpu_map          *aggr_map;
-static int                     (*aggr_get_id)(struct cpu_map *m, int cpu);
+static aggr_get_id_t           aggr_get_id;
 
 struct perf_stat {
        bool                     record;
@@ -1158,6 +1160,7 @@ static int stat__set_big_num(const struct option *opt 
__maybe_unused,
        return 0;
 }
 
+
 static int perf_stat__get_socket(struct cpu_map *map, int cpu)
 {
        return cpu_map__get_socket(map, cpu, NULL);
@@ -1168,22 +1171,63 @@ static int perf_stat__get_core(struct cpu_map *map, int 
cpu)
        return cpu_map__get_core(map, cpu, NULL);
 }
 
+static int cpu_map__get_max(struct cpu_map *map)
+{
+       int i, max = -1;
+
+       for (i = 0; i < map->nr; i++) {
+               if (map->map[i] > max)
+                       max = map->map[i];
+       }
+
+       return max;
+}
+
+static struct cpu_map *cpus_aggr_map;
+
+static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int 
idx)
+{
+       int cpu;
+
+       if (idx > map->nr)
+               return -1;
+
+       cpu = map->map[idx];
+
+       if (cpus_aggr_map->map[cpu] == -1)
+               cpus_aggr_map->map[cpu] = get_id(map, idx);
+
+       return cpus_aggr_map->map[cpu];
+}
+
+static int perf_stat__get_socket_cached(struct cpu_map *map, int idx)
+{
+       return perf_stat__get_aggr(perf_stat__get_socket, map, idx);
+}
+
+static int perf_stat__get_core_cached(struct cpu_map *map, int idx)
+{
+       return perf_stat__get_aggr(perf_stat__get_core, map, idx);
+}
+
 static int perf_stat_init_aggr_mode(void)
 {
+       int nr;
+
        switch (stat_config.aggr_mode) {
        case AGGR_SOCKET:
                if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
                        perror("cannot build socket map");
                        return -1;
                }
-               aggr_get_id = perf_stat__get_socket;
+               aggr_get_id = perf_stat__get_socket_cached;
                break;
        case AGGR_CORE:
                if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
                        perror("cannot build core map");
                        return -1;
                }
-               aggr_get_id = perf_stat__get_core;
+               aggr_get_id = perf_stat__get_core_cached;
                break;
        case AGGR_NONE:
        case AGGR_GLOBAL:
@@ -1192,7 +1236,15 @@ static int perf_stat_init_aggr_mode(void)
        default:
                break;
        }
-       return 0;
+
+       /*
+        * The evsel_list->cpus is the base we operate on,
+        * taking the highest cpu number to be the size of
+        * the aggregation translate cpumap.
+        */
+       nr = cpu_map__get_max(evsel_list->cpus);
+       cpus_aggr_map = cpu_map__empty_new(nr + 1);
+       return cpus_aggr_map ? 0 : -ENOMEM;
 }
 
 /*
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to