tools lib: Adopt zalloc()/zfree() from tools/perf
[platform/kernel/linux-starfive.git] / tools / perf / util / cputopo.c
index ece0710..fa1778a 100644 (file)
@@ -1,18 +1,23 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <sys/param.h>
+#include <sys/utsname.h>
 #include <inttypes.h>
+#include <stdlib.h>
 #include <api/fs/fs.h>
+#include <linux/zalloc.h>
 
 #include "cputopo.h"
 #include "cpumap.h"
-#include "util.h"
 #include "env.h"
 
-
 #define CORE_SIB_FMT \
        "%s/devices/system/cpu/cpu%d/topology/core_siblings_list"
+#define DIE_SIB_FMT \
+       "%s/devices/system/cpu/cpu%d/topology/die_cpus_list"
 #define THRD_SIB_FMT \
        "%s/devices/system/cpu/cpu%d/topology/thread_siblings_list"
+#define THRD_SIB_FMT_NEW \
+       "%s/devices/system/cpu/cpu%d/topology/core_cpus_list"
 #define NODE_ONLINE_FMT \
        "%s/devices/system/node/online"
 #define NODE_MEMINFO_FMT \
@@ -34,12 +39,12 @@ static int build_cpu_topology(struct cpu_topology *tp, int cpu)
                  sysfs__mountpoint(), cpu);
        fp = fopen(filename, "r");
        if (!fp)
-               goto try_threads;
+               goto try_dies;
 
        sret = getline(&buf, &len, fp);
        fclose(fp);
        if (sret <= 0)
-               goto try_threads;
+               goto try_dies;
 
        p = strchr(buf, '\n');
        if (p)
@@ -57,9 +62,44 @@ static int build_cpu_topology(struct cpu_topology *tp, int cpu)
        }
        ret = 0;
 
+try_dies:
+       if (!tp->die_siblings)
+               goto try_threads;
+
+       scnprintf(filename, MAXPATHLEN, DIE_SIB_FMT,
+                 sysfs__mountpoint(), 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->die_sib; i++) {
+               if (!strcmp(buf, tp->die_siblings[i]))
+                       break;
+       }
+       if (i == tp->die_sib) {
+               tp->die_siblings[i] = buf;
+               tp->die_sib++;
+               buf = NULL;
+               len = 0;
+       }
+       ret = 0;
+
 try_threads:
-       scnprintf(filename, MAXPATHLEN, THRD_SIB_FMT,
+       scnprintf(filename, MAXPATHLEN, THRD_SIB_FMT_NEW,
                  sysfs__mountpoint(), cpu);
+       if (access(filename, F_OK) == -1) {
+               scnprintf(filename, MAXPATHLEN, THRD_SIB_FMT,
+                         sysfs__mountpoint(), cpu);
+       }
        fp = fopen(filename, "r");
        if (!fp)
                goto done;
@@ -98,21 +138,46 @@ void cpu_topology__delete(struct cpu_topology *tp)
        for (i = 0 ; i < tp->core_sib; i++)
                zfree(&tp->core_siblings[i]);
 
+       if (tp->die_sib) {
+               for (i = 0 ; i < tp->die_sib; i++)
+                       zfree(&tp->die_siblings[i]);
+       }
+
        for (i = 0 ; i < tp->thread_sib; i++)
                zfree(&tp->thread_siblings[i]);
 
        free(tp);
 }
 
+static bool has_die_topology(void)
+{
+       char filename[MAXPATHLEN];
+       struct utsname uts;
+
+       if (uname(&uts) < 0)
+               return false;
+
+       if (strncmp(uts.machine, "x86_64", 6))
+               return false;
+
+       scnprintf(filename, MAXPATHLEN, DIE_SIB_FMT,
+                 sysfs__mountpoint(), 0);
+       if (access(filename, F_OK) == -1)
+               return false;
+
+       return true;
+}
+
 struct cpu_topology *cpu_topology__new(void)
 {
        struct cpu_topology *tp = NULL;
        void *addr;
-       u32 nr, i;
+       u32 nr, i, nr_addr;
        size_t sz;
        long ncpus;
        int ret = -1;
        struct cpu_map *map;
+       bool has_die = has_die_topology();
 
        ncpus = cpu__max_present_cpu();
 
@@ -126,7 +191,11 @@ struct cpu_topology *cpu_topology__new(void)
        nr = (u32)(ncpus & UINT_MAX);
 
        sz = nr * sizeof(char *);
-       addr = calloc(1, sizeof(*tp) + 2 * sz);
+       if (has_die)
+               nr_addr = 3;
+       else
+               nr_addr = 2;
+       addr = calloc(1, sizeof(*tp) + nr_addr * sz);
        if (!addr)
                goto out_free;
 
@@ -134,6 +203,10 @@ struct cpu_topology *cpu_topology__new(void)
        addr += sizeof(*tp);
        tp->core_siblings = addr;
        addr += sz;
+       if (has_die) {
+               tp->die_siblings = addr;
+               addr += sz;
+       }
        tp->thread_siblings = addr;
 
        for (i = 0; i < nr; i++) {