Commit 409a8be61560c5875816da6dcb0c575d78145a5c

Authored by Arnaldo Carvalho de Melo
1 parent e227051b13

perf tools: Add sort by src line/number

Using addr2line for now, requires debuginfo, needs more work to support
detached debuginfo, aka foo-debuginfo packages.

Example:

	[root@sandy ~]# perf record -a sleep 3
	[ perf record: Woken up 1 times to write data ]
	[ perf record: Captured and wrote 0.555 MB perf.data (~24236 samples) ]
	[root@sandy ~]# perf report -s dso,srcline 2>&1 | grep -v ^# | head -5
	    22.41%  [kernel.kallsyms]  /home/git/linux/drivers/idle/intel_idle.c:280
	     4.79%  [kernel.kallsyms]  /home/git/linux/drivers/cpuidle/cpuidle.c:148
	     4.78%  [kernel.kallsyms]  /home/git/linux/arch/x86/include/asm/atomic64_64.h:121
	     4.49%  [kernel.kallsyms]  /home/git/linux/kernel/sched/core.c:1690
	     4.30%  [kernel.kallsyms]  /home/git/linux/include/linux/seqlock.h:90
	[root@sandy ~]#

[root@sandy ~]# perf top -U -s dso,symbol,srcline
Samples: 1K of event 'cycles', Event count (approx.): 589617389
 18.66%  [kernel]  [k] copy_user_generic_unrolled   /home/git/linux/arch/x86/lib/copy_user_64.S:143
  7.83%  [kernel]  [k] clear_page                   /home/git/linux/arch/x86/lib/clear_page_64.S:39
  6.59%  [kernel]  [k] clear_page                   /home/git/linux/arch/x86/lib/clear_page_64.S:38
  3.66%  [kernel]  [k] page_fault                   /home/git/linux/arch/x86/kernel/entry_64.S:1379
  3.25%  [kernel]  [k] clear_page                   /home/git/linux/arch/x86/lib/clear_page_64.S:40
  3.12%  [kernel]  [k] clear_page                   /home/git/linux/arch/x86/lib/clear_page_64.S:37
  2.74%  [kernel]  [k] clear_page                   /home/git/linux/arch/x86/lib/clear_page_64.S:36
  2.39%  [kernel]  [k] clear_page                   /home/git/linux/arch/x86/lib/clear_page_64.S:43
  2.12%  [kernel]  [k] ioread32                     /home/git/linux/lib/iomap.c:90
  1.51%  [kernel]  [k] copy_user_generic_unrolled   /home/git/linux/arch/x86/lib/copy_user_64.S:144
  1.19%  [kernel]  [k] copy_user_generic_unrolled   /home/git/linux/arch/x86/lib/copy_user_64.S:154

Suggested-by: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-pdmqbng9twz06jzkbgtuwbp8@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

Showing 5 changed files with 54 additions and 2 deletions Side-by-side Diff

tools/perf/Documentation/perf-report.txt
... ... @@ -57,7 +57,7 @@
57 57  
58 58 -s::
59 59 --sort=::
60   - Sort by key(s): pid, comm, dso, symbol, parent.
  60 + Sort by key(s): pid, comm, dso, symbol, parent, srcline.
61 61  
62 62 -p::
63 63 --parent=<regex>::
tools/perf/Documentation/perf-top.txt
... ... @@ -112,7 +112,7 @@
112 112  
113 113 -s::
114 114 --sort::
115   - Sort by key(s): pid, comm, dso, symbol, parent
  115 + Sort by key(s): pid, comm, dso, symbol, parent, srcline.
116 116  
117 117 -n::
118 118 --show-nr-samples::
tools/perf/util/hist.h
... ... @@ -47,6 +47,7 @@
47 47 HISTC_SYMBOL_TO,
48 48 HISTC_DSO_FROM,
49 49 HISTC_DSO_TO,
  50 + HISTC_SRCLINE,
50 51 HISTC_NR_COLS, /* Last entry */
51 52 };
52 53  
tools/perf/util/sort.c
... ... @@ -241,6 +241,54 @@
241 241 .se_width_idx = HISTC_SYMBOL,
242 242 };
243 243  
  244 +/* --sort srcline */
  245 +
  246 +static int64_t
  247 +sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
  248 +{
  249 + return (int64_t)(right->ip - left->ip);
  250 +}
  251 +
  252 +static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf,
  253 + size_t size, unsigned int width __used)
  254 +{
  255 + FILE *fp;
  256 + char cmd[PATH_MAX + 2], *path = self->srcline, *nl;
  257 + size_t line_len;
  258 +
  259 + if (path != NULL)
  260 + goto out_path;
  261 +
  262 + snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64,
  263 + self->ms.map->dso->long_name, self->ip);
  264 + fp = popen(cmd, "r");
  265 + if (!fp)
  266 + goto out_ip;
  267 +
  268 + if (getline(&path, &line_len, fp) < 0 || !line_len)
  269 + goto out_ip;
  270 + fclose(fp);
  271 + self->srcline = strdup(path);
  272 + if (self->srcline == NULL)
  273 + goto out_ip;
  274 +
  275 + nl = strchr(self->srcline, '\n');
  276 + if (nl != NULL)
  277 + *nl = '\0';
  278 + path = self->srcline;
  279 +out_path:
  280 + return repsep_snprintf(bf, size, "%s", path);
  281 +out_ip:
  282 + return repsep_snprintf(bf, size, "%-#*llx", BITS_PER_LONG / 4, self->ip);
  283 +}
  284 +
  285 +struct sort_entry sort_srcline = {
  286 + .se_header = "Source:Line",
  287 + .se_cmp = sort__srcline_cmp,
  288 + .se_snprintf = hist_entry__srcline_snprintf,
  289 + .se_width_idx = HISTC_SRCLINE,
  290 +};
  291 +
244 292 /* --sort parent */
245 293  
246 294 static int64_t
... ... @@ -439,6 +487,7 @@
439 487 DIM(SORT_PARENT, "parent", sort_parent),
440 488 DIM(SORT_CPU, "cpu", sort_cpu),
441 489 DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
  490 + DIM(SORT_SRCLINE, "srcline", sort_srcline),
442 491 };
443 492  
444 493 int sort_dimension__add(const char *tok)
tools/perf/util/sort.h
... ... @@ -71,6 +71,7 @@
71 71 char level;
72 72 bool used;
73 73 u8 filtered;
  74 + char *srcline;
74 75 struct symbol *parent;
75 76 union {
76 77 unsigned long position;
... ... @@ -93,6 +94,7 @@
93 94 SORT_SYM_FROM,
94 95 SORT_SYM_TO,
95 96 SORT_MISPREDICT,
  97 + SORT_SRCLINE,
96 98 };
97 99  
98 100 /*