diff options
author | Kan Liang <kan.liang@intel.com> | 2017-08-29 13:11:09 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2017-09-01 13:46:11 -0400 |
commit | 8780fb25ab060bafa5a8149e79b703e0fc7ee847 (patch) | |
tree | 9fb7e634b284b332f4e06982ff63cc40a44f77d2 | |
parent | 3b0a5daa061076b2b75ffc294e74483ad9bf241a (diff) |
perf sort: Add sort option for physical address
Add a new sort option "phys_daddr" for --mem-mode sort. With this
option applied, perf can sort and report by sample's physical address.
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-3-git-send-email-kan.liang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/Documentation/perf-report.txt | 1 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 4 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 1 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 8 | ||||
-rw-r--r-- | tools/perf/util/session.c | 3 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 42 | ||||
-rw-r--r-- | tools/perf/util/sort.h | 1 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 1 |
8 files changed, 59 insertions, 2 deletions
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 9fa84617181e..383a98d992ed 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt | |||
@@ -137,6 +137,7 @@ OPTIONS | |||
137 | - mem: type of memory access for the data at the time of the sample | 137 | - mem: type of memory access for the data at the time of the sample |
138 | - snoop: type of snoop (if any) for the data at the time of the sample | 138 | - snoop: type of snoop (if any) for the data at the time of the sample |
139 | - dcacheline: the cacheline the data address is on at the time of the sample | 139 | - dcacheline: the cacheline the data address is on at the time of the sample |
140 | - phys_daddr: physical address of data being executed on at the time of sample | ||
140 | 141 | ||
141 | And the default sort keys are changed to local_weight, mem, sym, dso, | 142 | And the default sort keys are changed to local_weight, mem, sym, dso, |
142 | symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'. | 143 | symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'. |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 9453b2e27015..e60d8d8ea4c2 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -167,6 +167,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) | |||
167 | symlen = unresolved_col_width + 4 + 2; | 167 | symlen = unresolved_col_width + 4 + 2; |
168 | hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO); | 168 | hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO); |
169 | } | 169 | } |
170 | |||
171 | hists__new_col_len(hists, HISTC_MEM_PHYS_DADDR, | ||
172 | unresolved_col_width + 4 + 2); | ||
173 | |||
170 | } else { | 174 | } else { |
171 | symlen = unresolved_col_width + 4 + 2; | 175 | symlen = unresolved_col_width + 4 + 2; |
172 | hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen); | 176 | hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen); |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index ee3670a388df..e60dda26a920 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -47,6 +47,7 @@ enum hist_column { | |||
47 | HISTC_GLOBAL_WEIGHT, | 47 | HISTC_GLOBAL_WEIGHT, |
48 | HISTC_MEM_DADDR_SYMBOL, | 48 | HISTC_MEM_DADDR_SYMBOL, |
49 | HISTC_MEM_DADDR_DSO, | 49 | HISTC_MEM_DADDR_DSO, |
50 | HISTC_MEM_PHYS_DADDR, | ||
50 | HISTC_MEM_LOCKED, | 51 | HISTC_MEM_LOCKED, |
51 | HISTC_MEM_TLB, | 52 | HISTC_MEM_TLB, |
52 | HISTC_MEM_LVL, | 53 | HISTC_MEM_LVL, |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 9eaa95302c86..df709363ef69 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -1635,10 +1635,12 @@ static void ip__resolve_ams(struct thread *thread, | |||
1635 | ams->al_addr = al.addr; | 1635 | ams->al_addr = al.addr; |
1636 | ams->sym = al.sym; | 1636 | ams->sym = al.sym; |
1637 | ams->map = al.map; | 1637 | ams->map = al.map; |
1638 | ams->phys_addr = 0; | ||
1638 | } | 1639 | } |
1639 | 1640 | ||
1640 | static void ip__resolve_data(struct thread *thread, | 1641 | static void ip__resolve_data(struct thread *thread, |
1641 | u8 m, struct addr_map_symbol *ams, u64 addr) | 1642 | u8 m, struct addr_map_symbol *ams, |
1643 | u64 addr, u64 phys_addr) | ||
1642 | { | 1644 | { |
1643 | struct addr_location al; | 1645 | struct addr_location al; |
1644 | 1646 | ||
@@ -1658,6 +1660,7 @@ static void ip__resolve_data(struct thread *thread, | |||
1658 | ams->al_addr = al.addr; | 1660 | ams->al_addr = al.addr; |
1659 | ams->sym = al.sym; | 1661 | ams->sym = al.sym; |
1660 | ams->map = al.map; | 1662 | ams->map = al.map; |
1663 | ams->phys_addr = phys_addr; | ||
1661 | } | 1664 | } |
1662 | 1665 | ||
1663 | struct mem_info *sample__resolve_mem(struct perf_sample *sample, | 1666 | struct mem_info *sample__resolve_mem(struct perf_sample *sample, |
@@ -1669,7 +1672,8 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, | |||
1669 | return NULL; | 1672 | return NULL; |
1670 | 1673 | ||
1671 | ip__resolve_ams(al->thread, &mi->iaddr, sample->ip); | 1674 | ip__resolve_ams(al->thread, &mi->iaddr, sample->ip); |
1672 | ip__resolve_data(al->thread, al->cpumode, &mi->daddr, sample->addr); | 1675 | ip__resolve_data(al->thread, al->cpumode, &mi->daddr, |
1676 | sample->addr, sample->phys_addr); | ||
1673 | mi->data_src.val = sample->data_src; | 1677 | mi->data_src.val = sample->data_src; |
1674 | 1678 | ||
1675 | return mi; | 1679 | return mi; |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index ac863691605f..a7ebd9fe8e40 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -1120,6 +1120,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, | |||
1120 | if (sample_type & PERF_SAMPLE_DATA_SRC) | 1120 | if (sample_type & PERF_SAMPLE_DATA_SRC) |
1121 | printf(" . data_src: 0x%"PRIx64"\n", sample->data_src); | 1121 | printf(" . data_src: 0x%"PRIx64"\n", sample->data_src); |
1122 | 1122 | ||
1123 | if (sample_type & PERF_SAMPLE_PHYS_ADDR) | ||
1124 | printf(" .. phys_addr: 0x%"PRIx64"\n", sample->phys_addr); | ||
1125 | |||
1123 | if (sample_type & PERF_SAMPLE_TRANSACTION) | 1126 | if (sample_type & PERF_SAMPLE_TRANSACTION) |
1124 | printf("... transaction: %" PRIx64 "\n", sample->transaction); | 1127 | printf("... transaction: %" PRIx64 "\n", sample->transaction); |
1125 | 1128 | ||
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 12359bd986db..eb3ab902a1c0 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -1316,6 +1316,47 @@ struct sort_entry sort_mem_dcacheline = { | |||
1316 | }; | 1316 | }; |
1317 | 1317 | ||
1318 | static int64_t | 1318 | static int64_t |
1319 | sort__phys_daddr_cmp(struct hist_entry *left, struct hist_entry *right) | ||
1320 | { | ||
1321 | uint64_t l = 0, r = 0; | ||
1322 | |||
1323 | if (left->mem_info) | ||
1324 | l = left->mem_info->daddr.phys_addr; | ||
1325 | if (right->mem_info) | ||
1326 | r = right->mem_info->daddr.phys_addr; | ||
1327 | |||
1328 | return (int64_t)(r - l); | ||
1329 | } | ||
1330 | |||
1331 | static int hist_entry__phys_daddr_snprintf(struct hist_entry *he, char *bf, | ||
1332 | size_t size, unsigned int width) | ||
1333 | { | ||
1334 | uint64_t addr = 0; | ||
1335 | size_t ret = 0; | ||
1336 | size_t len = BITS_PER_LONG / 4; | ||
1337 | |||
1338 | addr = he->mem_info->daddr.phys_addr; | ||
1339 | |||
1340 | ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", he->level); | ||
1341 | |||
1342 | ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", len, addr); | ||
1343 | |||
1344 | ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, ""); | ||
1345 | |||
1346 | if (ret > width) | ||
1347 | bf[width] = '\0'; | ||
1348 | |||
1349 | return width; | ||
1350 | } | ||
1351 | |||
1352 | struct sort_entry sort_mem_phys_daddr = { | ||
1353 | .se_header = "Data Physical Address", | ||
1354 | .se_cmp = sort__phys_daddr_cmp, | ||
1355 | .se_snprintf = hist_entry__phys_daddr_snprintf, | ||
1356 | .se_width_idx = HISTC_MEM_PHYS_DADDR, | ||
1357 | }; | ||
1358 | |||
1359 | static int64_t | ||
1319 | sort__abort_cmp(struct hist_entry *left, struct hist_entry *right) | 1360 | sort__abort_cmp(struct hist_entry *left, struct hist_entry *right) |
1320 | { | 1361 | { |
1321 | if (!left->branch_info || !right->branch_info) | 1362 | if (!left->branch_info || !right->branch_info) |
@@ -1547,6 +1588,7 @@ static struct sort_dimension memory_sort_dimensions[] = { | |||
1547 | DIM(SORT_MEM_LVL, "mem", sort_mem_lvl), | 1588 | DIM(SORT_MEM_LVL, "mem", sort_mem_lvl), |
1548 | DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop), | 1589 | DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop), |
1549 | DIM(SORT_MEM_DCACHELINE, "dcacheline", sort_mem_dcacheline), | 1590 | DIM(SORT_MEM_DCACHELINE, "dcacheline", sort_mem_dcacheline), |
1591 | DIM(SORT_MEM_PHYS_DADDR, "phys_daddr", sort_mem_phys_daddr), | ||
1550 | }; | 1592 | }; |
1551 | 1593 | ||
1552 | #undef DIM | 1594 | #undef DIM |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index b7c75597e18f..f36dc4980a6c 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -245,6 +245,7 @@ enum sort_type { | |||
245 | SORT_MEM_SNOOP, | 245 | SORT_MEM_SNOOP, |
246 | SORT_MEM_DCACHELINE, | 246 | SORT_MEM_DCACHELINE, |
247 | SORT_MEM_IADDR_SYMBOL, | 247 | SORT_MEM_IADDR_SYMBOL, |
248 | SORT_MEM_PHYS_DADDR, | ||
248 | }; | 249 | }; |
249 | 250 | ||
250 | /* | 251 | /* |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index d00a012cfdfb..2bd6a1f01a1c 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -186,6 +186,7 @@ struct addr_map_symbol { | |||
186 | struct symbol *sym; | 186 | struct symbol *sym; |
187 | u64 addr; | 187 | u64 addr; |
188 | u64 al_addr; | 188 | u64 al_addr; |
189 | u64 phys_addr; | ||
189 | }; | 190 | }; |
190 | 191 | ||
191 | struct branch_info { | 192 | struct branch_info { |