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: <1371824448-7306-9-git-send-email-eranian@google.com>
Date:	Fri, 21 Jun 2013 16:20:48 +0200
From:	Stephane Eranian <eranian@...gle.com>
To:	linux-kernel@...r.kernel.org
Cc:	peterz@...radead.org, mingo@...e.hu, ak@...ux.intel.com,
	acme@...hat.com, jolsa@...hat.com, namhyung.kim@....com
Subject: [PATCH 8/8] perf mem: add physical addr sampling support

This patch adds support for PERF_SAMPLE_PHYS_ADDR to perf mem
and supporting code in the infrastructure.

Signed-off-by: Stephane Eranian <eranian@...gle.com>
---
 tools/perf/builtin-mem.c    | 116 +++++++++++++++++++++++++++++++++-----------
 tools/perf/builtin-report.c |   2 +-
 tools/perf/util/hist.c      |   4 +-
 tools/perf/util/hist.h      |   1 +
 tools/perf/util/machine.c   |   1 +
 tools/perf/util/sort.c      |  42 ++++++++++++++++
 tools/perf/util/sort.h      |   1 +
 tools/perf/util/symbol.h    |   1 +
 8 files changed, 139 insertions(+), 29 deletions(-)

diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index a8ff6d2..5946f6a 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -17,6 +17,7 @@ struct perf_mem {
 	symbol_filter_t		annotate_init;
 	bool			hide_unresolved;
 	bool			dump_raw;
+	bool			phys_addr;
 	const char		*cpu_list;
 	DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
 };
@@ -26,14 +27,14 @@ static const char * const mem_usage[] = {
 	NULL
 };
 
-static int __cmd_record(int argc, const char **argv)
+static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
 {
 	int rec_argc, i = 0, j;
 	const char **rec_argv;
 	char event[64];
 	int ret;
 
-	rec_argc = argc + 4;
+	rec_argc = argc + 5;
 	rec_argv = calloc(rec_argc + 1, sizeof(char *));
 	if (!rec_argv)
 		return -1;
@@ -42,6 +43,10 @@ static int __cmd_record(int argc, const char **argv)
 	if (!strcmp(mem_operation, MEM_OPERATION_LOAD))
 		rec_argv[i++] = strdup("-W");
 	rec_argv[i++] = strdup("-d");
+
+	if (mem->phys_addr)
+		rec_argv[i++] = strdup("--phys-addr");
+
 	rec_argv[i++] = strdup("-e");
 
 	if (strcmp(mem_operation, MEM_OPERATION_LOAD))
@@ -83,29 +88,62 @@ dump_raw_samples(struct perf_tool *tool,
 		al.map->dso->hit = 1;
 
 	if (symbol_conf.field_sep) {
-		fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64
-		      "%s0x%"PRIx64"%s%s:%s\n";
+		if (mem->phys_addr)
+			fmt = "%d%s%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s0x%"PRIx64
+			      "%s%"PRIu64"%s0x%"PRIx64"%s%s:%s\n";
+		else
+			fmt = "%d%s%d%s%d%s0x%"PRIx64"%s0x%"PRIx64
+			      "%s%"PRIu64"%s0x%"PRIx64"%s%s:%s\n";
 	} else {
-		fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64
-		      "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n";
+		if (mem->phys_addr)
+			fmt = "%5d%s%5d%s%5d%s0x%016"PRIx64"%s0x%016"PRIx64
+			      "%s0x016%"PRIx64"%s%5"PRIu64"%s0x%06"
+			      PRIx64"%s%s:%s\n";
+		else
+			fmt = "%5d%s%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64
+			      "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n";
 		symbol_conf.field_sep = " ";
 	}
-
-	printf(fmt,
-		sample->pid,
-		symbol_conf.field_sep,
-		sample->tid,
-		symbol_conf.field_sep,
-		event->ip.ip,
-		symbol_conf.field_sep,
-		sample->addr,
-		symbol_conf.field_sep,
-		sample->weight,
-		symbol_conf.field_sep,
-		sample->data_src,
-		symbol_conf.field_sep,
-		al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???",
-		al.sym ? al.sym->name : "???");
+	if (mem->phys_addr)
+		printf(fmt,
+		       sample->pid,
+		       symbol_conf.field_sep,
+		       sample->tid,
+		       symbol_conf.field_sep,
+		       sample->cpu,
+		       symbol_conf.field_sep,
+		       event->ip.ip,
+		       symbol_conf.field_sep,
+		       sample->addr,
+		       symbol_conf.field_sep,
+		       sample->paddr,
+		       symbol_conf.field_sep,
+		       sample->weight,
+		       symbol_conf.field_sep,
+		       sample->data_src,
+		       symbol_conf.field_sep,
+		       al.map ? (al.map->dso ?
+				 al.map->dso->long_name : "???") : "???",
+		       al.sym ? al.sym->name : "???");
+	else
+		printf(fmt,
+		       sample->pid,
+		       symbol_conf.field_sep,
+		       sample->tid,
+		       symbol_conf.field_sep,
+		       sample->cpu,
+		       symbol_conf.field_sep,
+		       event->ip.ip,
+		       symbol_conf.field_sep,
+		       sample->addr,
+		       symbol_conf.field_sep,
+		       sample->weight,
+		       symbol_conf.field_sep,
+		       sample->data_src,
+		       symbol_conf.field_sep,
+		       al.map ? (al.map->dso ?
+				 al.map->dso->long_name : "???") : "???",
+		       al.sym ? al.sym->name : "???");
 
 	return 0;
 }
@@ -139,7 +177,10 @@ static int report_raw_events(struct perf_mem *mem)
 	if (symbol__init() < 0)
 		return -1;
 
-	printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
+	if (mem->phys_addr)
+		printf("# PID, TID, CPU, IP, ADDR, PADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
+	else
+		printf("# PID, TID, CPU, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
 
 	err = perf_session__process_events(session, &mem->tool);
 	if (err)
@@ -152,15 +193,33 @@ out_delete:
 	return err;
 }
 
+static const char *ld_sort_order = "--sort=mem,sym,dso,symbol_daddr,dso_daddr,"
+				   "tlb,locked";
+static const char *st_sort_order = "--sort=local_weight,mem,sym,dso,"
+				   "symbol_daddr,dso_daddr,snoop,tlb,locked";
+static const char *ld_sort_order_p = "--sort=mem,sym,dso,symbol_daddr,"
+				     "symbol_paddr,dso_daddr,tlb,locked";
+static const char *st_sort_order_p = "--sort=local_weight,mem,sym,dso,"
+				     "symbol_daddr,symbol_paddr,dso_daddr,snoop,tlb,locked";
+
 static int report_events(int argc, const char **argv, struct perf_mem *mem)
 {
 	const char **rep_argv;
+	const char *ld_sort, *st_sort;
 	int ret, i = 0, j, rep_argc;
 
 	if (mem->dump_raw)
 		return report_raw_events(mem);
 
-	rep_argc = argc + 3;
+	if (mem->phys_addr) {
+		ld_sort = ld_sort_order_p;
+		st_sort = st_sort_order_p;
+	} else {
+		ld_sort = ld_sort_order;
+		st_sort = st_sort_order;
+	}
+
+	rep_argc = argc + 4;
 	rep_argv = calloc(rep_argc + 1, sizeof(char *));
 	if (!rep_argv)
 		return -1;
@@ -174,8 +233,9 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem)
 	 * the column
 	 */
 	if (strcmp(mem_operation, MEM_OPERATION_LOAD))
-		rep_argv[i++] = strdup("--sort=mem,sym,dso,symbol_daddr,"
-				       "dso_daddr,tlb,locked");
+		rep_argv[i++] = strdup(st_sort);
+	else
+		rep_argv[i++] = strdup(ld_sort);
 
 	for (j = 1; j < argc; j++, i++)
 		rep_argv[i] = argv[j];
@@ -207,6 +267,8 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused)
 		    "dump raw samples in ASCII"),
 	OPT_BOOLEAN('U', "hide-unresolved", &mem.hide_unresolved,
 		    "Only display entries resolved to a symbol"),
+	OPT_BOOLEAN(0, "phys-addr", &mem.phys_addr,
+		    "sample physical data addr"),
 	OPT_STRING('i', "input", &input_name, "file",
 		   "input file name"),
 	OPT_STRING('C', "cpu", &mem.cpu_list, "cpu",
@@ -232,7 +294,7 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused)
 	}
 
 	if (!strncmp(argv[0], "rec", 3))
-		return __cmd_record(argc, argv);
+		return __cmd_record(argc, argv, &mem);
 	else if (!strncmp(argv[0], "rep", 3))
 		return report_events(argc, argv, &mem);
 	else
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index ca98d34..6b2531f 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -894,7 +894,7 @@ repeat:
 		 * branch-mode specific order
 		 */
 		if (sort_order == default_sort_order)
-			sort_order = "local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked";
+			sort_order = "local_weight,mem,sym,dso,symbol_daddr,symbol_paddr,dso_daddr,snoop,tlb,locked";
 	}
 
 	if (setup_sorting() < 0)
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index b11a6cf..136a851 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -148,10 +148,12 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
 			hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
 		}
 	} else {
-		symlen = unresolved_col_width + 4 + 2;
+		symlen = unresolved_col_width + 2 + 4;
 		hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen);
 		hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
 	}
+	symlen = unresolved_col_width + 2;
+	hists__new_col_len(hists, HISTC_MEM_PADDR_SYMBOL, symlen);
 
 	hists__new_col_len(hists, HISTC_MEM_LOCKED, 6);
 	hists__new_col_len(hists, HISTC_MEM_TLB, 22);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 2d3790f..9add9ae 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -52,6 +52,7 @@ enum hist_column {
 	HISTC_LOCAL_WEIGHT,
 	HISTC_GLOBAL_WEIGHT,
 	HISTC_MEM_DADDR_SYMBOL,
+	HISTC_MEM_PADDR_SYMBOL,
 	HISTC_MEM_DADDR_DSO,
 	HISTC_MEM_LOCKED,
 	HISTC_MEM_TLB,
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index b2ecad6..7823460 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1133,6 +1133,7 @@ struct mem_info *machine__resolve_mem(struct machine *machine,
 	ip__resolve_ams(machine, thr, &mi->iaddr, sample->ip);
 	ip__resolve_data(machine, thr, cpumode, &mi->daddr, sample->addr);
 	mi->data_src.val = sample->data_src;
+	mi->paddr = sample->paddr;
 
 	return mi;
 }
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 313a5a7..1a0ea58 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -497,6 +497,39 @@ static int hist_entry__daddr_snprintf(struct hist_entry *self, char *bf,
 }
 
 static int64_t
+sort__paddr_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+	uint64_t l = 0, r = 0;
+
+	if (left->mem_info)
+		l = left->mem_info->paddr;
+	if (right->mem_info)
+		r = right->mem_info->paddr;
+
+	return (int64_t)(r - l);
+}
+
+static int hist_entry__paddr_snprintf(struct hist_entry *self, char *bf,
+				    size_t size, unsigned int width)
+{
+	uint64_t addr = 0;
+	size_t len = BITS_PER_LONG / 4;
+	int ret = 0;
+
+	if (!self->mem_info)
+		return 0;
+
+	addr = self->mem_info->paddr;
+
+	ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx",
+			       len, addr);
+	ret += repsep_snprintf(bf + ret, size - ret, "%-*s",
+			       width - ret, "");
+	return ret;
+}
+
+
+static int64_t
 sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
 {
 	struct map *map_l = NULL;
@@ -821,6 +854,14 @@ struct sort_entry sort_mem_daddr_sym = {
 	.se_width_idx	= HISTC_MEM_DADDR_SYMBOL,
 };
 
+struct sort_entry sort_mem_paddr_sym = {
+	.se_header	= "Data Physical Addr",
+	.se_cmp		= sort__paddr_cmp,
+	.se_snprintf	= hist_entry__paddr_snprintf,
+	.se_width_idx	= HISTC_MEM_PADDR_SYMBOL,
+};
+
+
 struct sort_entry sort_mem_daddr_dso = {
 	.se_header	= "Data Object",
 	.se_cmp		= sort__dso_daddr_cmp,
@@ -894,6 +935,7 @@ static struct sort_dimension memory_sort_dimensions[] = {
 	DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
 	DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
 	DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
+	DIM(SORT_MEM_PADDR_SYMBOL, "symbol_paddr", sort_mem_paddr_sym),
 	DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
 	DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
 	DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 45ac84c..4d4bdce 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -152,6 +152,7 @@ enum sort_type {
 	SORT_LOCAL_WEIGHT = __SORT_MEMORY_MODE,
 	SORT_GLOBAL_WEIGHT,
 	SORT_MEM_DADDR_SYMBOL,
+	SORT_MEM_PADDR_SYMBOL,
 	SORT_MEM_DADDR_DSO,
 	SORT_MEM_LOCKED,
 	SORT_MEM_TLB,
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 5f720dc..c2e933c 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -159,6 +159,7 @@ struct branch_info {
 struct mem_info {
 	struct addr_map_symbol iaddr;
 	struct addr_map_symbol daddr;
+	u64		       paddr;
 	union perf_mem_data_src data_src;
 };
 
-- 
1.8.1.2

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