diff options
author | Andi Kleen <ak@linux.intel.com> | 2015-08-07 18:54:24 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-08-10 16:20:25 -0400 |
commit | 31191a85fb875cf123cea56bbfd34f4b941f3c79 (patch) | |
tree | cd2cce745f743947fbad074781a4e3ae311d03a1 | |
parent | e8e6d37e73e6b950c891c780745460b87f4755b6 (diff) |
perf report: Add support for srcfile sort key
In some cases it's useful to characterize samples by file. This is
useful to get a higher level categorization, for example to map cost to
subsystems.
Add a srcfile sort key to perf report. It builds on top of the existing
srcline support.
Commiter notes:
E.g.:
# perf record -F 10000 usleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.016 MB perf.data (13 samples) ]
[root@zoo ~]# perf report -s srcfile --stdio
# Total Lost Samples: 0
#
# Samples: 13 of event 'cycles'
# Event count (approx.): 869878
#
# Overhead Source File
# ........ ...........
60.99% .
20.62% paravirt.h
14.23% rmap.c
4.04% signal.c
0.11% msr.h
#
The first line is collecting all the files for which srcfiles couldn't somehow
get resolved to:
# perf report -s srcfile,dso --stdio
# Total Lost Samples: 0
#
# Samples: 13 of event 'cycles'
# Event count (approx.): 869878
#
# Overhead Source File Shared Object
# ........ ........... ................
40.97% . ld-2.20.so
20.62% paravirt.h [kernel.vmlinux]
20.02% . libc-2.20.so
14.23% rmap.c [kernel.vmlinux]
4.04% signal.c [kernel.vmlinux]
0.11% msr.h [kernel.vmlinux]
#
XXX: Investigate why that is not resolving on Fedora 21, Andi says he hasn't
seen this on Fedora 22.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/1438988064-21834-1-git-send-email-andi@firstfloor.org
[ Added column length update, from 0e65bdb3f90f ('perf hists: Update the column width for the "srcline" sort key') ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/Documentation/perf-report.txt | 2 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 5 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 1 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 52 | ||||
-rw-r--r-- | tools/perf/util/sort.h | 2 |
5 files changed, 62 insertions, 0 deletions
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 1a782ef02b68..7b07d19e2d54 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt | |||
@@ -81,6 +81,8 @@ OPTIONS | |||
81 | - cpu: cpu number the task ran at the time of sample | 81 | - cpu: cpu number the task ran at the time of sample |
82 | - srcline: filename and line number executed at the time of sample. The | 82 | - srcline: filename and line number executed at the time of sample. The |
83 | DWARF debugging info must be provided. | 83 | DWARF debugging info must be provided. |
84 | - srcfile: file name of the source file of the same. Requires dwarf | ||
85 | information. | ||
84 | - weight: Event specific weight, e.g. memory latency or transaction | 86 | - weight: Event specific weight, e.g. memory latency or transaction |
85 | abort cost. This is the global weight. | 87 | abort cost. This is the global weight. |
86 | - local_weight: Local weight version of the weight above. | 88 | - local_weight: Local weight version of the weight above. |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 608c0a7fd0f4..6bccfae334b1 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -154,6 +154,9 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) | |||
154 | if (h->srcline) | 154 | if (h->srcline) |
155 | hists__new_col_len(hists, HISTC_SRCLINE, strlen(h->srcline)); | 155 | hists__new_col_len(hists, HISTC_SRCLINE, strlen(h->srcline)); |
156 | 156 | ||
157 | if (h->srcfile) | ||
158 | hists__new_col_len(hists, HISTC_SRCFILE, strlen(h->srcfile)); | ||
159 | |||
157 | if (h->transaction) | 160 | if (h->transaction) |
158 | hists__new_col_len(hists, HISTC_TRANSACTION, | 161 | hists__new_col_len(hists, HISTC_TRANSACTION, |
159 | hist_entry__transaction_len()); | 162 | hist_entry__transaction_len()); |
@@ -949,6 +952,8 @@ void hist_entry__delete(struct hist_entry *he) | |||
949 | 952 | ||
950 | zfree(&he->stat_acc); | 953 | zfree(&he->stat_acc); |
951 | free_srcline(he->srcline); | 954 | free_srcline(he->srcline); |
955 | if (he->srcfile && he->srcfile[0]) | ||
956 | free(he->srcfile); | ||
952 | free_callchain(he->callchain); | 957 | free_callchain(he->callchain); |
953 | free(he); | 958 | free(he); |
954 | } | 959 | } |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index e2f712f85d2e..bc528d54e457 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -30,6 +30,7 @@ enum hist_column { | |||
30 | HISTC_PARENT, | 30 | HISTC_PARENT, |
31 | HISTC_CPU, | 31 | HISTC_CPU, |
32 | HISTC_SRCLINE, | 32 | HISTC_SRCLINE, |
33 | HISTC_SRCFILE, | ||
33 | HISTC_MISPREDICT, | 34 | HISTC_MISPREDICT, |
34 | HISTC_IN_TX, | 35 | HISTC_IN_TX, |
35 | HISTC_ABORT, | 36 | HISTC_ABORT, |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 5177088a71d3..c0c32b050e45 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -319,6 +319,57 @@ struct sort_entry sort_srcline = { | |||
319 | .se_width_idx = HISTC_SRCLINE, | 319 | .se_width_idx = HISTC_SRCLINE, |
320 | }; | 320 | }; |
321 | 321 | ||
322 | /* --sort srcfile */ | ||
323 | |||
324 | static char no_srcfile[1]; | ||
325 | |||
326 | static char *get_srcfile(struct hist_entry *e) | ||
327 | { | ||
328 | char *sf, *p; | ||
329 | struct map *map = e->ms.map; | ||
330 | |||
331 | sf = get_srcline(map->dso, map__rip_2objdump(map, e->ip), | ||
332 | e->ms.sym, true); | ||
333 | p = strchr(sf, ':'); | ||
334 | if (p && *sf) { | ||
335 | *p = 0; | ||
336 | return sf; | ||
337 | } | ||
338 | free(sf); | ||
339 | return no_srcfile; | ||
340 | } | ||
341 | |||
342 | static int64_t | ||
343 | sort__srcfile_cmp(struct hist_entry *left, struct hist_entry *right) | ||
344 | { | ||
345 | if (!left->srcfile) { | ||
346 | if (!left->ms.map) | ||
347 | left->srcfile = no_srcfile; | ||
348 | else | ||
349 | left->srcfile = get_srcfile(left); | ||
350 | } | ||
351 | if (!right->srcfile) { | ||
352 | if (!right->ms.map) | ||
353 | right->srcfile = no_srcfile; | ||
354 | else | ||
355 | right->srcfile = get_srcfile(right); | ||
356 | } | ||
357 | return strcmp(right->srcfile, left->srcfile); | ||
358 | } | ||
359 | |||
360 | static int hist_entry__srcfile_snprintf(struct hist_entry *he, char *bf, | ||
361 | size_t size, unsigned int width) | ||
362 | { | ||
363 | return repsep_snprintf(bf, size, "%-*.*s", width, width, he->srcfile); | ||
364 | } | ||
365 | |||
366 | struct sort_entry sort_srcfile = { | ||
367 | .se_header = "Source File", | ||
368 | .se_cmp = sort__srcfile_cmp, | ||
369 | .se_snprintf = hist_entry__srcfile_snprintf, | ||
370 | .se_width_idx = HISTC_SRCFILE, | ||
371 | }; | ||
372 | |||
322 | /* --sort parent */ | 373 | /* --sort parent */ |
323 | 374 | ||
324 | static int64_t | 375 | static int64_t |
@@ -1196,6 +1247,7 @@ static struct sort_dimension common_sort_dimensions[] = { | |||
1196 | DIM(SORT_PARENT, "parent", sort_parent), | 1247 | DIM(SORT_PARENT, "parent", sort_parent), |
1197 | DIM(SORT_CPU, "cpu", sort_cpu), | 1248 | DIM(SORT_CPU, "cpu", sort_cpu), |
1198 | DIM(SORT_SRCLINE, "srcline", sort_srcline), | 1249 | DIM(SORT_SRCLINE, "srcline", sort_srcline), |
1250 | DIM(SORT_SRCFILE, "srcfile", sort_srcfile), | ||
1199 | DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight), | 1251 | DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight), |
1200 | DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight), | 1252 | DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight), |
1201 | DIM(SORT_TRANSACTION, "transaction", sort_transaction), | 1253 | DIM(SORT_TRANSACTION, "transaction", sort_transaction), |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index bc6c87a76d16..3c2a399f8f5b 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -114,6 +114,7 @@ struct hist_entry { | |||
114 | }; | 114 | }; |
115 | }; | 115 | }; |
116 | char *srcline; | 116 | char *srcline; |
117 | char *srcfile; | ||
117 | struct symbol *parent; | 118 | struct symbol *parent; |
118 | struct rb_root sorted_chain; | 119 | struct rb_root sorted_chain; |
119 | struct branch_info *branch_info; | 120 | struct branch_info *branch_info; |
@@ -172,6 +173,7 @@ enum sort_type { | |||
172 | SORT_PARENT, | 173 | SORT_PARENT, |
173 | SORT_CPU, | 174 | SORT_CPU, |
174 | SORT_SRCLINE, | 175 | SORT_SRCLINE, |
176 | SORT_SRCFILE, | ||
175 | SORT_LOCAL_WEIGHT, | 177 | SORT_LOCAL_WEIGHT, |
176 | SORT_GLOBAL_WEIGHT, | 178 | SORT_GLOBAL_WEIGHT, |
177 | SORT_TRANSACTION, | 179 | SORT_TRANSACTION, |