perf mem: Support physical address

Add option phys-data in "perf mem" to record/report physical address.
The default mem sort order for physical address is changed accordingly.

Signed-off-by: Kan Liang <kan.liang@intel.com>
Tested-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Stephane Eranian <eranian@google.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1504026672-7304-4-git-send-email-kan.liang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Kan Liang 2017-08-29 13:11:10 -04:00 коммит произвёл Arnaldo Carvalho de Melo
Родитель 8780fb25ab
Коммит c35aeb9dfe
2 изменённых файлов: 76 добавлений и 27 удалений

Просмотреть файл

@ -59,6 +59,10 @@ OPTIONS
--ldload:: --ldload::
Specify desired latency for loads event. Specify desired latency for loads event.
-p::
--phys-data::
Record/Report sample physical addresses
SEE ALSO SEE ALSO
-------- --------
linkperf:perf-record[1], linkperf:perf-report[1] linkperf:perf-record[1], linkperf:perf-report[1]

Просмотреть файл

@ -23,6 +23,7 @@ struct perf_mem {
bool hide_unresolved; bool hide_unresolved;
bool dump_raw; bool dump_raw;
bool force; bool force;
bool phys_addr;
int operation; int operation;
const char *cpu_list; const char *cpu_list;
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
@ -101,6 +102,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
rec_argv[i++] = "-d"; rec_argv[i++] = "-d";
if (mem->phys_addr)
rec_argv[i++] = "--phys-data";
for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
if (!perf_mem_events[j].record) if (!perf_mem_events[j].record)
continue; continue;
@ -161,6 +165,35 @@ dump_raw_samples(struct perf_tool *tool,
if (al.map != NULL) if (al.map != NULL)
al.map->dso->hit = 1; al.map->dso->hit = 1;
if (mem->phys_addr) {
if (symbol_conf.field_sep) {
fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s0x%016"PRIx64
"%s%"PRIu64"%s0x%"PRIx64"%s%s:%s\n";
} else {
fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64
"%s0x%016"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,
sample->ip,
symbol_conf.field_sep,
sample->addr,
symbol_conf.field_sep,
sample->phys_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 : "???");
} else {
if (symbol_conf.field_sep) { if (symbol_conf.field_sep) {
fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64 fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64
"%s0x%"PRIx64"%s%s:%s\n"; "%s0x%"PRIx64"%s%s:%s\n";
@ -185,6 +218,7 @@ dump_raw_samples(struct perf_tool *tool,
symbol_conf.field_sep, symbol_conf.field_sep,
al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???",
al.sym ? al.sym->name : "???"); al.sym ? al.sym->name : "???");
}
out_put: out_put:
addr_location__put(&al); addr_location__put(&al);
return 0; return 0;
@ -224,6 +258,9 @@ static int report_raw_events(struct perf_mem *mem)
if (ret < 0) if (ret < 0)
goto out_delete; goto out_delete;
if (mem->phys_addr)
printf("# PID, TID, IP, ADDR, PHYS ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
else
printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
ret = perf_session__process_events(session); ret = perf_session__process_events(session);
@ -254,9 +291,16 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem)
* there is no weight (cost) associated with stores, so don't print * there is no weight (cost) associated with stores, so don't print
* the column * the column
*/ */
if (!(mem->operation & MEM_OPERATION_LOAD)) if (!(mem->operation & MEM_OPERATION_LOAD)) {
if (mem->phys_addr)
rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr,"
"dso_daddr,tlb,locked,phys_daddr";
else
rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr,"
"dso_daddr,tlb,locked"; "dso_daddr,tlb,locked";
} else if (mem->phys_addr)
rep_argv[i++] = "--sort=local_weight,mem,sym,dso,symbol_daddr,"
"dso_daddr,snoop,tlb,locked,phys_daddr";
for (j = 1; j < argc; j++, i++) for (j = 1; j < argc; j++, i++)
rep_argv[i] = argv[j]; rep_argv[i] = argv[j];
@ -373,6 +417,7 @@ int cmd_mem(int argc, const char **argv)
"separator for columns, no spaces will be added" "separator for columns, no spaces will be added"
" between columns '.' is reserved."), " between columns '.' is reserved."),
OPT_BOOLEAN('f', "force", &mem.force, "don't complain, do it"), OPT_BOOLEAN('f', "force", &mem.force, "don't complain, do it"),
OPT_BOOLEAN('p', "phys-data", &mem.phys_addr, "Record/Report sample physical addresses"),
OPT_END() OPT_END()
}; };
const char *const mem_subcommands[] = { "record", "report", NULL }; const char *const mem_subcommands[] = { "record", "report", NULL };