From: Kan Liang <kan.li...@intel.com>

This patch stores cpu socket_id and core_id in perf.date, and read them
to perf_env in header process.

Signed-off-by: Kan Liang <kan.li...@intel.com>
---

Changes since V1:
 - Store core_id and socket_id in perf.date

 tools/perf/util/header.c  | 97 +++++++++++++++++++++++++++++++++++++++++++++--
 tools/perf/util/header.h  |  6 +++
 tools/perf/util/session.c |  1 +
 3 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 4181454..482749f 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -439,14 +439,42 @@ static int write_cmdline(int fd, struct perf_header *h 
__maybe_unused,
        "/sys/devices/system/cpu/cpu%d/topology/core_siblings_list"
 #define THRD_SIB_FMT \
        "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
+#define CORE_ID_FMT \
+       "/sys/devices/system/cpu/cpu%d/topology/core_id"
+#define PHY_PKG_ID_FMT \
+       "/sys/devices/system/cpu/cpu%d/topology/physical_package_id"
 
 struct cpu_topo {
+       u32 cpu_nr;
        u32 core_sib;
        u32 thread_sib;
        char **core_siblings;
        char **thread_siblings;
+       int *core_id;
+       int *phy_pkg_id;
 };
 
+static int read_id(const char *path, int cpu)
+{
+       FILE *fp;
+       char filename[MAXPATHLEN];
+       char *buf = NULL;
+       size_t len = 0;
+       int ret = -1;
+
+       sprintf(filename, path, cpu);
+       fp = fopen(filename, "r");
+       if (fp == NULL)
+               return ret;
+
+       if (getline(&buf, &len, fp) > 0)
+               ret = atoi(buf);
+
+       fclose(fp);
+       free(buf);
+       return ret;
+}
+
 static int build_cpu_topo(struct cpu_topo *tp, int cpu)
 {
        FILE *fp;
@@ -507,6 +535,9 @@ try_threads:
        }
        ret = 0;
 done:
+       tp->core_id[cpu] = read_id(CORE_ID_FMT, cpu);
+       tp->phy_pkg_id[cpu] = read_id(PHY_PKG_ID_FMT, cpu);
+
        if(fp)
                fclose(fp);
        free(buf);
@@ -534,7 +565,7 @@ static struct cpu_topo *build_cpu_topology(void)
        struct cpu_topo *tp;
        void *addr;
        u32 nr, i;
-       size_t sz;
+       size_t sz, sz_id;
        long ncpus;
        int ret = -1;
 
@@ -545,17 +576,22 @@ static struct cpu_topo *build_cpu_topology(void)
        nr = (u32)(ncpus & UINT_MAX);
 
        sz = nr * sizeof(char *);
+       sz_id = nr * sizeof(int);
 
-       addr = calloc(1, sizeof(*tp) + 2 * sz);
+       addr = calloc(1, sizeof(*tp) + 2 * sz + 2 * sz_id);
        if (!addr)
                return NULL;
 
        tp = addr;
-
+       tp->cpu_nr = nr;
        addr += sizeof(*tp);
        tp->core_siblings = addr;
        addr += sz;
        tp->thread_siblings = addr;
+       addr += sz;
+       tp->core_id = addr;
+       addr += sz_id;
+       tp->phy_pkg_id = addr;
 
        for (i = 0; i < nr; i++) {
                ret = build_cpu_topo(tp, i);
@@ -598,6 +634,15 @@ static int write_cpu_topology(int fd, struct perf_header 
*h __maybe_unused,
                if (ret < 0)
                        break;
        }
+
+       for (i = 0; i < tp->cpu_nr; i++) {
+               ret = do_write(fd, &tp->core_id[i], sizeof(int));
+               if (ret < 0)
+                       return ret;
+               ret = do_write(fd, &tp->phy_pkg_id[i], sizeof(int));
+               if (ret < 0)
+                       return ret;
+       }
 done:
        free_cpu_topo(tp);
        return ret;
@@ -938,6 +983,7 @@ static void print_cpu_topology(struct perf_header *ph, int 
fd __maybe_unused,
 {
        int nr, i;
        char *str;
+       int cpu_nr = ph->env.nr_cpus_online;
 
        nr = ph->env.nr_sibling_cores;
        str = ph->env.sibling_cores;
@@ -954,6 +1000,10 @@ static void print_cpu_topology(struct perf_header *ph, 
int fd __maybe_unused,
                fprintf(fp, "# sibling threads : %s\n", str);
                str += strlen(str) + 1;
        }
+
+       for (i = 0; i < cpu_nr; i++)
+               fprintf(fp, "# CPU %d: Core ID %d, Socket ID %d\n", i,
+                       ph->env.cpu[i].core_id, ph->env.cpu[i].socket_id);
 }
 
 static void free_event_desc(struct perf_evsel *events)
@@ -1590,10 +1640,15 @@ static int process_cpu_topology(struct 
perf_file_section *section __maybe_unused
        u32 nr, i;
        char *str;
        struct strbuf sb;
+       int cpu_nr = ph->env.nr_cpus_online;
+
+       ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu));
+       if (!ph->env.cpu)
+               return -1;
 
        ret = readn(fd, &nr, sizeof(nr));
        if (ret != sizeof(nr))
-               return -1;
+               goto free_cpu;
 
        if (ph->needs_swap)
                nr = bswap_32(nr);
@@ -1631,10 +1686,44 @@ static int process_cpu_topology(struct 
perf_file_section *section __maybe_unused
                free(str);
        }
        ph->env.sibling_threads = strbuf_detach(&sb, NULL);
+
+       for (i = 0; i < (u32)cpu_nr; i++) {
+               ret = readn(fd, &nr, sizeof(nr));
+               if (ret != sizeof(nr))
+                       goto free_cpu;
+
+               if (ph->needs_swap)
+                       nr = bswap_32(nr);
+
+               if (nr > (u32)cpu_nr) {
+                       pr_debug("core_id number is too big."
+                                "You may need to upgrade the perf tool.\n");
+                       goto free_cpu;
+               }
+               ph->env.cpu[i].core_id = nr;
+
+               ret = readn(fd, &nr, sizeof(nr));
+               if (ret != sizeof(nr))
+                       goto free_cpu;
+
+               if (ph->needs_swap)
+                       nr = bswap_32(nr);
+
+               if (nr > (u32)cpu_nr) {
+                       pr_debug("socket_id number is too big."
+                                "You may need to upgrade the perf tool.\n");
+                       goto free_cpu;
+               }
+
+               ph->env.cpu[i].socket_id = nr;
+       }
+
        return 0;
 
 error:
        strbuf_release(&sb);
+free_cpu:
+       free(ph->env.cpu);
        return -1;
 }
 
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 396e496..975d803 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -66,6 +66,11 @@ struct perf_header;
 int perf_file_header__read(struct perf_file_header *header,
                           struct perf_header *ph, int fd);
 
+struct cpu_topology_map {
+       int     socket_id;
+       int     core_id;
+};
+
 struct perf_env {
        char                    *hostname;
        char                    *os_release;
@@ -89,6 +94,7 @@ struct perf_env {
        char                    *sibling_threads;
        char                    *numa_nodes;
        char                    *pmu_mappings;
+       struct cpu_topology_map *cpu;
 };
 
 struct perf_header {
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8a4537e..61669be 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -185,6 +185,7 @@ static void perf_session_env__exit(struct perf_env *env)
        zfree(&env->sibling_threads);
        zfree(&env->numa_nodes);
        zfree(&env->pmu_mappings);
+       zfree(&env->cpu);
 }
 
 void perf_session__delete(struct perf_session *session)
-- 
1.8.3.1

--
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