perf tools: Add cpu_topology object
authorJiri Olsa <jolsa@kernel.org>
Tue, 19 Feb 2019 09:58:13 +0000 (10:58 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 19 Feb 2019 15:21:01 +0000 (12:21 -0300)
Make struct cpu_topo global and rename it to 'struct cpu_topology', so
that it can be used from the 'perf record' command in the following
patches.

Add the following interface functions to load/free cpu topology details:

  struct cpu_topology *cpu_topology__new(void);
  void cpu_topology__delete(struct cpu_topology *tp);

Move it to a separate source file cputopo.c together with numa related
object in the following patches.

No functional change, the new interface will be used in upcoming changes.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20190219095815.15931-3-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/Build
tools/perf/util/cputopo.c [new file with mode: 0644]
tools/perf/util/cputopo.h [new file with mode: 0644]
tools/perf/util/header.c

index ca0741c919035d54468ea01bc145e3c2a8192938..3008d49fa587a94c87d536fdc2a99ac7ef688c20 100644 (file)
@@ -69,6 +69,7 @@ perf-y += hist.o
 perf-y += util.o
 perf-y += xyarray.o
 perf-y += cpumap.o
+perf-y += cputopo.o
 perf-y += cgroup.o
 perf-y += target.o
 perf-y += rblist.o
diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c
new file mode 100644 (file)
index 0000000..84470ed
--- /dev/null
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <sys/param.h>
+
+#include "cputopo.h"
+#include "cpumap.h"
+#include "util.h"
+
+
+#define CORE_SIB_FMT \
+       "/sys/devices/system/cpu/cpu%d/topology/core_siblings_list"
+#define THRD_SIB_FMT \
+       "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
+
+static int build_cpu_topology(struct cpu_topology *tp, int cpu)
+{
+       FILE *fp;
+       char filename[MAXPATHLEN];
+       char *buf = NULL, *p;
+       size_t len = 0;
+       ssize_t sret;
+       u32 i = 0;
+       int ret = -1;
+
+       sprintf(filename, CORE_SIB_FMT, cpu);
+       fp = fopen(filename, "r");
+       if (!fp)
+               goto try_threads;
+
+       sret = getline(&buf, &len, fp);
+       fclose(fp);
+       if (sret <= 0)
+               goto try_threads;
+
+       p = strchr(buf, '\n');
+       if (p)
+               *p = '\0';
+
+       for (i = 0; i < tp->core_sib; i++) {
+               if (!strcmp(buf, tp->core_siblings[i]))
+                       break;
+       }
+       if (i == tp->core_sib) {
+               tp->core_siblings[i] = buf;
+               tp->core_sib++;
+               buf = NULL;
+               len = 0;
+       }
+       ret = 0;
+
+try_threads:
+       sprintf(filename, THRD_SIB_FMT, cpu);
+       fp = fopen(filename, "r");
+       if (!fp)
+               goto done;
+
+       if (getline(&buf, &len, fp) <= 0)
+               goto done;
+
+       p = strchr(buf, '\n');
+       if (p)
+               *p = '\0';
+
+       for (i = 0; i < tp->thread_sib; i++) {
+               if (!strcmp(buf, tp->thread_siblings[i]))
+                       break;
+       }
+       if (i == tp->thread_sib) {
+               tp->thread_siblings[i] = buf;
+               tp->thread_sib++;
+               buf = NULL;
+       }
+       ret = 0;
+done:
+       if (fp)
+               fclose(fp);
+       free(buf);
+       return ret;
+}
+
+void cpu_topology__delete(struct cpu_topology *tp)
+{
+       u32 i;
+
+       if (!tp)
+               return;
+
+       for (i = 0 ; i < tp->core_sib; i++)
+               zfree(&tp->core_siblings[i]);
+
+       for (i = 0 ; i < tp->thread_sib; i++)
+               zfree(&tp->thread_siblings[i]);
+
+       free(tp);
+}
+
+struct cpu_topology *cpu_topology__new(void)
+{
+       struct cpu_topology *tp = NULL;
+       void *addr;
+       u32 nr, i;
+       size_t sz;
+       long ncpus;
+       int ret = -1;
+       struct cpu_map *map;
+
+       ncpus = cpu__max_present_cpu();
+
+       /* build online CPU map */
+       map = cpu_map__new(NULL);
+       if (map == NULL) {
+               pr_debug("failed to get system cpumap\n");
+               return NULL;
+       }
+
+       nr = (u32)(ncpus & UINT_MAX);
+
+       sz = nr * sizeof(char *);
+       addr = calloc(1, sizeof(*tp) + 2 * sz);
+       if (!addr)
+               goto out_free;
+
+       tp = addr;
+       addr += sizeof(*tp);
+       tp->core_siblings = addr;
+       addr += sz;
+       tp->thread_siblings = addr;
+
+       for (i = 0; i < nr; i++) {
+               if (!cpu_map__has(map, i))
+                       continue;
+
+               ret = build_cpu_topology(tp, i);
+               if (ret < 0)
+                       break;
+       }
+
+out_free:
+       cpu_map__put(map);
+       if (ret) {
+               cpu_topology__delete(tp);
+               tp = NULL;
+       }
+       return tp;
+}
diff --git a/tools/perf/util/cputopo.h b/tools/perf/util/cputopo.h
new file mode 100644 (file)
index 0000000..4b5f411
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PERF_CPUTOPO_H
+#define __PERF_CPUTOPO_H
+
+#include <linux/types.h>
+
+struct cpu_topology {
+       u32       core_sib;
+       u32       thread_sib;
+       char    **core_siblings;
+       char    **thread_siblings;
+};
+
+struct cpu_topology *cpu_topology__new(void);
+void cpu_topology__delete(struct cpu_topology *tp);
+
+#endif /* __PERF_CPUTOPO_H */
index c66f26ec557a0879e073c9f4cd3504c4a585bff1..80ac57e6d38f9bdf7c97f127aa5cf0a18a586fac 100644 (file)
@@ -39,6 +39,7 @@
 #include "tool.h"
 #include "time-utils.h"
 #include "units.h"
+#include "cputopo.h"
 
 #include "sane_ctype.h"
 
@@ -557,158 +558,15 @@ static int write_cmdline(struct feat_fd *ff,
        return 0;
 }
 
-#define CORE_SIB_FMT \
-       "/sys/devices/system/cpu/cpu%d/topology/core_siblings_list"
-#define THRD_SIB_FMT \
-       "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
-
-struct cpu_topo {
-       u32 core_sib;
-       u32 thread_sib;
-       char **core_siblings;
-       char **thread_siblings;
-};
-
-static int build_cpu_topo(struct cpu_topo *tp, int cpu)
-{
-       FILE *fp;
-       char filename[MAXPATHLEN];
-       char *buf = NULL, *p;
-       size_t len = 0;
-       ssize_t sret;
-       u32 i = 0;
-       int ret = -1;
-
-       sprintf(filename, CORE_SIB_FMT, cpu);
-       fp = fopen(filename, "r");
-       if (!fp)
-               goto try_threads;
-
-       sret = getline(&buf, &len, fp);
-       fclose(fp);
-       if (sret <= 0)
-               goto try_threads;
-
-       p = strchr(buf, '\n');
-       if (p)
-               *p = '\0';
-
-       for (i = 0; i < tp->core_sib; i++) {
-               if (!strcmp(buf, tp->core_siblings[i]))
-                       break;
-       }
-       if (i == tp->core_sib) {
-               tp->core_siblings[i] = buf;
-               tp->core_sib++;
-               buf = NULL;
-               len = 0;
-       }
-       ret = 0;
-
-try_threads:
-       sprintf(filename, THRD_SIB_FMT, cpu);
-       fp = fopen(filename, "r");
-       if (!fp)
-               goto done;
-
-       if (getline(&buf, &len, fp) <= 0)
-               goto done;
-
-       p = strchr(buf, '\n');
-       if (p)
-               *p = '\0';
-
-       for (i = 0; i < tp->thread_sib; i++) {
-               if (!strcmp(buf, tp->thread_siblings[i]))
-                       break;
-       }
-       if (i == tp->thread_sib) {
-               tp->thread_siblings[i] = buf;
-               tp->thread_sib++;
-               buf = NULL;
-       }
-       ret = 0;
-done:
-       if(fp)
-               fclose(fp);
-       free(buf);
-       return ret;
-}
-
-static void free_cpu_topo(struct cpu_topo *tp)
-{
-       u32 i;
-
-       if (!tp)
-               return;
-
-       for (i = 0 ; i < tp->core_sib; i++)
-               zfree(&tp->core_siblings[i]);
-
-       for (i = 0 ; i < tp->thread_sib; i++)
-               zfree(&tp->thread_siblings[i]);
-
-       free(tp);
-}
-
-static struct cpu_topo *build_cpu_topology(void)
-{
-       struct cpu_topo *tp = NULL;
-       void *addr;
-       u32 nr, i;
-       size_t sz;
-       long ncpus;
-       int ret = -1;
-       struct cpu_map *map;
-
-       ncpus = cpu__max_present_cpu();
-
-       /* build online CPU map */
-       map = cpu_map__new(NULL);
-       if (map == NULL) {
-               pr_debug("failed to get system cpumap\n");
-               return NULL;
-       }
-
-       nr = (u32)(ncpus & UINT_MAX);
-
-       sz = nr * sizeof(char *);
-       addr = calloc(1, sizeof(*tp) + 2 * sz);
-       if (!addr)
-               goto out_free;
-
-       tp = addr;
-       addr += sizeof(*tp);
-       tp->core_siblings = addr;
-       addr += sz;
-       tp->thread_siblings = addr;
-
-       for (i = 0; i < nr; i++) {
-               if (!cpu_map__has(map, i))
-                       continue;
-
-               ret = build_cpu_topo(tp, i);
-               if (ret < 0)
-                       break;
-       }
-
-out_free:
-       cpu_map__put(map);
-       if (ret) {
-               free_cpu_topo(tp);
-               tp = NULL;
-       }
-       return tp;
-}
 
 static int write_cpu_topology(struct feat_fd *ff,
                              struct perf_evlist *evlist __maybe_unused)
 {
-       struct cpu_topo *tp;
+       struct cpu_topology *tp;
        u32 i;
        int ret, j;
 
-       tp = build_cpu_topology();
+       tp = cpu_topology__new();
        if (!tp)
                return -1;
 
@@ -746,7 +604,7 @@ static int write_cpu_topology(struct feat_fd *ff,
                        return ret;
        }
 done:
-       free_cpu_topo(tp);
+       cpu_topology__delete(tp);
        return ret;
 }