Messages in this thread Patch in this message | | | From | Kan Liang <> | Subject | [PATCH V2 1/2] perf,tools: store cpu socket_id and core_id in perf.date | Date | Fri, 28 Aug 2015 09:43:38 -0400 |
| |
From: Kan Liang <kan.liang@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.liang@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
| |