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:
Родитель
8780fb25ab
Коммит
c35aeb9dfe
|
@ -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 };
|
||||||
|
|
Загрузка…
Ссылка в новой задаче