diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-05-30 09:33:24 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-06-19 12:06:18 -0400 |
commit | 409a8be61560c5875816da6dcb0c575d78145a5c (patch) | |
tree | c840e43aba2c75171d656c458432ce1f8008c99a | |
parent | e227051b13956b8f71c0abecc41ad351e64671c8 (diff) |
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>
-rw-r--r-- | tools/perf/Documentation/perf-report.txt | 2 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-top.txt | 2 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 1 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 49 | ||||
-rw-r--r-- | tools/perf/util/sort.h | 2 |
5 files changed, 54 insertions, 2 deletions
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 2d89f02719b5..495210a612c4 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt | |||
@@ -57,7 +57,7 @@ OPTIONS | |||
57 | 57 | ||
58 | -s:: | 58 | -s:: |
59 | --sort=:: | 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 | -p:: | 62 | -p:: |
63 | --parent=<regex>:: | 63 | --parent=<regex>:: |
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 4a5680cb242e..5b80d84d6b4a 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt | |||
@@ -112,7 +112,7 @@ Default is to monitor all CPUS. | |||
112 | 112 | ||
113 | -s:: | 113 | -s:: |
114 | --sort:: | 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 | -n:: | 117 | -n:: |
118 | --show-nr-samples:: | 118 | --show-nr-samples:: |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 34bb556d6219..0b096c27a419 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -47,6 +47,7 @@ enum hist_column { | |||
47 | HISTC_SYMBOL_TO, | 47 | HISTC_SYMBOL_TO, |
48 | HISTC_DSO_FROM, | 48 | HISTC_DSO_FROM, |
49 | HISTC_DSO_TO, | 49 | HISTC_DSO_TO, |
50 | HISTC_SRCLINE, | ||
50 | HISTC_NR_COLS, /* Last entry */ | 51 | HISTC_NR_COLS, /* Last entry */ |
51 | }; | 52 | }; |
52 | 53 | ||
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index a27237430c5f..0f5a0a496bc4 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -241,6 +241,54 @@ struct sort_entry sort_sym = { | |||
241 | .se_width_idx = HISTC_SYMBOL, | 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 | /* --sort parent */ | 292 | /* --sort parent */ |
245 | 293 | ||
246 | static int64_t | 294 | static int64_t |
@@ -439,6 +487,7 @@ static struct sort_dimension sort_dimensions[] = { | |||
439 | DIM(SORT_PARENT, "parent", sort_parent), | 487 | DIM(SORT_PARENT, "parent", sort_parent), |
440 | DIM(SORT_CPU, "cpu", sort_cpu), | 488 | DIM(SORT_CPU, "cpu", sort_cpu), |
441 | DIM(SORT_MISPREDICT, "mispredict", sort_mispredict), | 489 | DIM(SORT_MISPREDICT, "mispredict", sort_mispredict), |
490 | DIM(SORT_SRCLINE, "srcline", sort_srcline), | ||
442 | }; | 491 | }; |
443 | 492 | ||
444 | int sort_dimension__add(const char *tok) | 493 | int sort_dimension__add(const char *tok) |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 472aa5a63a58..e724b26acd51 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -71,6 +71,7 @@ struct hist_entry { | |||
71 | char level; | 71 | char level; |
72 | bool used; | 72 | bool used; |
73 | u8 filtered; | 73 | u8 filtered; |
74 | char *srcline; | ||
74 | struct symbol *parent; | 75 | struct symbol *parent; |
75 | union { | 76 | union { |
76 | unsigned long position; | 77 | unsigned long position; |
@@ -93,6 +94,7 @@ enum sort_type { | |||
93 | SORT_SYM_FROM, | 94 | SORT_SYM_FROM, |
94 | SORT_SYM_TO, | 95 | SORT_SYM_TO, |
95 | SORT_MISPREDICT, | 96 | SORT_MISPREDICT, |
97 | SORT_SRCLINE, | ||
96 | }; | 98 | }; |
97 | 99 | ||
98 | /* | 100 | /* |