lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1441020082-6345-2-git-send-email-kan.liang@intel.com>
Date:	Mon, 31 Aug 2015 07:21:21 -0400
From:	Kan Liang <kan.liang@...el.com>
To:	acme@...nel.org, jolsa@...nel.org
Cc:	ak@...ux.intel.com, linux-kernel@...r.kernel.org,
	Kan Liang <kan.liang@...el.com>
Subject: [PATCH V3 2/3] perf,tools: store cpu socket_id and core_id in perf.date

From: Kan Liang <kan.liang@...el.com>

This patch stores cpu socket_id and core_id in perf.date, and read them
to perf_env in header process.
Although the changes modify the CPU_TOPOLOGY feature, the old perf still
can correctly read new perf.data. Because the new codes are added at the
end of the cpu_topology section. The old perf can ignore the extra data.
For reading old perf.data, new perf will error out and leave message in
debug mode. So the user can upgrade the perf accordingly.

Signed-off-by: Kan Liang <kan.liang@...el.com>
---

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

Changes since V2:
 - Use funcitons in cpumap.c to get core_id and socket_id
 - Modify changelog

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

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 4181454..a1451f3 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -441,10 +441,13 @@ static int write_cmdline(int fd, struct perf_header *h __maybe_unused,
 	"/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
 
 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 build_cpu_topo(struct cpu_topo *tp, int cpu)
@@ -507,6 +510,9 @@ try_threads:
 	}
 	ret = 0;
 done:
+	tp->core_id[cpu] = cpu_map__get_core_id(cpu);
+	tp->phy_pkg_id[cpu] = cpu_map__get_socket_id(cpu);
+
 	if(fp)
 		fclose(fp);
 	free(buf);
@@ -534,7 +540,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 +551,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 +609,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 +958,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 +975,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 +1615,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 +1661,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 majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ