diff options
author | Kan Liang <kan.liang@intel.com> | 2017-08-29 13:11:10 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2017-09-01 13:46:23 -0400 |
commit | c35aeb9dfe512422ca9ea28aae692c8f1d052b2d (patch) | |
tree | d8e16d7be6cb3aa8a33f138579dc1190b3c9dad9 /tools | |
parent | 8780fb25ab060bafa5a8149e79b703e0fc7ee847 (diff) |
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>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Documentation/perf-mem.txt | 4 | ||||
-rw-r--r-- | tools/perf/builtin-mem.c | 97 |
2 files changed, 75 insertions, 26 deletions
diff --git a/tools/perf/Documentation/perf-mem.txt b/tools/perf/Documentation/perf-mem.txt index 73496320fca3..4be08a1e3f8d 100644 --- a/tools/perf/Documentation/perf-mem.txt +++ b/tools/perf/Documentation/perf-mem.txt | |||
@@ -59,6 +59,10 @@ OPTIONS | |||
59 | --ldload:: | 59 | --ldload:: |
60 | Specify desired latency for loads event. | 60 | Specify desired latency for loads event. |
61 | 61 | ||
62 | -p:: | ||
63 | --phys-data:: | ||
64 | Record/Report sample physical addresses | ||
65 | |||
62 | SEE ALSO | 66 | SEE ALSO |
63 | -------- | 67 | -------- |
64 | linkperf:perf-record[1], linkperf:perf-report[1] | 68 | linkperf:perf-record[1], linkperf:perf-report[1] |
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index e001c0290793..0f15634ef82c 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c | |||
@@ -23,6 +23,7 @@ struct perf_mem { | |||
23 | bool hide_unresolved; | 23 | bool hide_unresolved; |
24 | bool dump_raw; | 24 | bool dump_raw; |
25 | bool force; | 25 | bool force; |
26 | bool phys_addr; | ||
26 | int operation; | 27 | int operation; |
27 | const char *cpu_list; | 28 | const char *cpu_list; |
28 | DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); | 29 | DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); |
@@ -101,6 +102,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) | |||
101 | 102 | ||
102 | rec_argv[i++] = "-d"; | 103 | rec_argv[i++] = "-d"; |
103 | 104 | ||
105 | if (mem->phys_addr) | ||
106 | rec_argv[i++] = "--phys-data"; | ||
107 | |||
104 | for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { | 108 | for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { |
105 | if (!perf_mem_events[j].record) | 109 | if (!perf_mem_events[j].record) |
106 | continue; | 110 | continue; |
@@ -161,30 +165,60 @@ dump_raw_samples(struct perf_tool *tool, | |||
161 | if (al.map != NULL) | 165 | if (al.map != NULL) |
162 | al.map->dso->hit = 1; | 166 | al.map->dso->hit = 1; |
163 | 167 | ||
164 | if (symbol_conf.field_sep) { | 168 | if (mem->phys_addr) { |
165 | fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64 | 169 | if (symbol_conf.field_sep) { |
166 | "%s0x%"PRIx64"%s%s:%s\n"; | 170 | fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s0x%016"PRIx64 |
171 | "%s%"PRIu64"%s0x%"PRIx64"%s%s:%s\n"; | ||
172 | } else { | ||
173 | fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64 | ||
174 | "%s0x%016"PRIx64"%s%5"PRIu64"%s0x%06"PRIx64 | ||
175 | "%s%s:%s\n"; | ||
176 | symbol_conf.field_sep = " "; | ||
177 | } | ||
178 | |||
179 | printf(fmt, | ||
180 | sample->pid, | ||
181 | symbol_conf.field_sep, | ||
182 | sample->tid, | ||
183 | symbol_conf.field_sep, | ||
184 | sample->ip, | ||
185 | symbol_conf.field_sep, | ||
186 | sample->addr, | ||
187 | symbol_conf.field_sep, | ||
188 | sample->phys_addr, | ||
189 | symbol_conf.field_sep, | ||
190 | sample->weight, | ||
191 | symbol_conf.field_sep, | ||
192 | sample->data_src, | ||
193 | symbol_conf.field_sep, | ||
194 | al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", | ||
195 | al.sym ? al.sym->name : "???"); | ||
167 | } else { | 196 | } else { |
168 | fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64 | 197 | if (symbol_conf.field_sep) { |
169 | "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n"; | 198 | fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64 |
170 | symbol_conf.field_sep = " "; | 199 | "%s0x%"PRIx64"%s%s:%s\n"; |
171 | } | 200 | } else { |
201 | fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64 | ||
202 | "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n"; | ||
203 | symbol_conf.field_sep = " "; | ||
204 | } | ||
172 | 205 | ||
173 | printf(fmt, | 206 | printf(fmt, |
174 | sample->pid, | 207 | sample->pid, |
175 | symbol_conf.field_sep, | 208 | symbol_conf.field_sep, |
176 | sample->tid, | 209 | sample->tid, |
177 | symbol_conf.field_sep, | 210 | symbol_conf.field_sep, |
178 | sample->ip, | 211 | sample->ip, |
179 | symbol_conf.field_sep, | 212 | symbol_conf.field_sep, |
180 | sample->addr, | 213 | sample->addr, |
181 | symbol_conf.field_sep, | 214 | symbol_conf.field_sep, |
182 | sample->weight, | 215 | sample->weight, |
183 | symbol_conf.field_sep, | 216 | symbol_conf.field_sep, |
184 | sample->data_src, | 217 | sample->data_src, |
185 | symbol_conf.field_sep, | 218 | symbol_conf.field_sep, |
186 | al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", | 219 | al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", |
187 | al.sym ? al.sym->name : "???"); | 220 | al.sym ? al.sym->name : "???"); |
221 | } | ||
188 | out_put: | 222 | out_put: |
189 | addr_location__put(&al); | 223 | addr_location__put(&al); |
190 | return 0; | 224 | return 0; |
@@ -224,7 +258,10 @@ static int report_raw_events(struct perf_mem *mem) | |||
224 | if (ret < 0) | 258 | if (ret < 0) |
225 | goto out_delete; | 259 | goto out_delete; |
226 | 260 | ||
227 | printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); | 261 | if (mem->phys_addr) |
262 | printf("# PID, TID, IP, ADDR, PHYS ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); | ||
263 | else | ||
264 | printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); | ||
228 | 265 | ||
229 | ret = perf_session__process_events(session); | 266 | ret = perf_session__process_events(session); |
230 | 267 | ||
@@ -254,9 +291,16 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem) | |||
254 | * there is no weight (cost) associated with stores, so don't print | 291 | * there is no weight (cost) associated with stores, so don't print |
255 | * the column | 292 | * the column |
256 | */ | 293 | */ |
257 | if (!(mem->operation & MEM_OPERATION_LOAD)) | 294 | if (!(mem->operation & MEM_OPERATION_LOAD)) { |
258 | rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," | 295 | if (mem->phys_addr) |
259 | "dso_daddr,tlb,locked"; | 296 | rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," |
297 | "dso_daddr,tlb,locked,phys_daddr"; | ||
298 | else | ||
299 | rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," | ||
300 | "dso_daddr,tlb,locked"; | ||
301 | } else if (mem->phys_addr) | ||
302 | rep_argv[i++] = "--sort=local_weight,mem,sym,dso,symbol_daddr," | ||
303 | "dso_daddr,snoop,tlb,locked,phys_daddr"; | ||
260 | 304 | ||
261 | for (j = 1; j < argc; j++, i++) | 305 | for (j = 1; j < argc; j++, i++) |
262 | rep_argv[i] = argv[j]; | 306 | rep_argv[i] = argv[j]; |
@@ -373,6 +417,7 @@ int cmd_mem(int argc, const char **argv) | |||
373 | "separator for columns, no spaces will be added" | 417 | "separator for columns, no spaces will be added" |
374 | " between columns '.' is reserved."), | 418 | " between columns '.' is reserved."), |
375 | OPT_BOOLEAN('f', "force", &mem.force, "don't complain, do it"), | 419 | OPT_BOOLEAN('f', "force", &mem.force, "don't complain, do it"), |
420 | OPT_BOOLEAN('p', "phys-data", &mem.phys_addr, "Record/Report sample physical addresses"), | ||
376 | OPT_END() | 421 | OPT_END() |
377 | }; | 422 | }; |
378 | const char *const mem_subcommands[] = { "record", "report", NULL }; | 423 | const char *const mem_subcommands[] = { "record", "report", NULL }; |