aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2015-08-07 18:54:24 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-08-10 16:20:25 -0400
commit31191a85fb875cf123cea56bbfd34f4b941f3c79 (patch)
treecd2cce745f743947fbad074781a4e3ae311d03a1
parente8e6d37e73e6b950c891c780745460b87f4755b6 (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.txt2
-rw-r--r--tools/perf/util/hist.c5
-rw-r--r--tools/perf/util/hist.h1
-rw-r--r--tools/perf/util/sort.c52
-rw-r--r--tools/perf/util/sort.h2
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
324static char no_srcfile[1];
325
326static 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
342static int64_t
343sort__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
360static 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
366struct 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
324static int64_t 375static 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,