diff options
author | Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> | 2014-10-21 20:09:58 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-10-29 08:32:46 -0400 |
commit | 7d073b335edc8d97af730c2e3b83ed6642bd3c27 (patch) | |
tree | 161f1cf4d4bf4f18c45a5e8de92a3ecc6b8027a2 /tools/perf | |
parent | 4cdcc33db2f0455f297b4e14e434ba311ec5ca06 (diff) |
perf tools powerpc: Cache the DWARF debug info
Cache the DWARF debug info for DSO so we don't have to rebuild it for each
address in the DSO.
Note that dso__new() uses calloc() so don't need to set dso->dwfl to NULL.
$ /tmp/perf.orig --version
perf version 3.18.rc1.gc2661b8
$ /tmp/perf.new --version
perf version 3.18.rc1.g402d62
$ perf stat -e cycles,instructions /tmp/perf.orig report -g > orig
Performance counter stats for '/tmp/perf.orig report -g':
6,428,177,183 cycles # 0.000 GHz
4,176,288,391 instructions # 0.65 insns per cycle
1.840666132 seconds time elapsed
$ perf stat -e cycles,instructions /tmp/perf.new report -g > new
Performance counter stats for '/tmp/perf.new report -g':
305,773,142 cycles # 0.000 GHz
276,048,272 instructions # 0.90 insns per cycle
0.087693543 seconds time elapsed
$ diff orig new
$
Changelog[v2]:
[Arnaldo Carvalho] Cache in existing global objects rather than create
new static/globals in functions.
Reported-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Anton Blanchard <anton@au1.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20141022000958.GB2228@us.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/arch/powerpc/util/skip-callchain-idx.c | 33 | ||||
-rw-r--r-- | tools/perf/util/dso.h | 1 |
2 files changed, 23 insertions, 11 deletions
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index d73ef8bb08c7..9892b0f0bec4 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c | |||
@@ -145,7 +145,7 @@ static Dwarf_Frame *get_dwarf_frame(Dwfl_Module *mod, Dwarf_Addr pc) | |||
145 | * yet used) | 145 | * yet used) |
146 | * -1 in case of errors | 146 | * -1 in case of errors |
147 | */ | 147 | */ |
148 | static int check_return_addr(const char *exec_file, Dwarf_Addr pc) | 148 | static int check_return_addr(struct dso *dso, Dwarf_Addr pc) |
149 | { | 149 | { |
150 | int rc = -1; | 150 | int rc = -1; |
151 | Dwfl *dwfl; | 151 | Dwfl *dwfl; |
@@ -156,15 +156,27 @@ static int check_return_addr(const char *exec_file, Dwarf_Addr pc) | |||
156 | Dwarf_Addr end = pc; | 156 | Dwarf_Addr end = pc; |
157 | bool signalp; | 157 | bool signalp; |
158 | 158 | ||
159 | dwfl = dwfl_begin(&offline_callbacks); | 159 | dwfl = dso->dwfl; |
160 | if (!dwfl) { | ||
161 | pr_debug("dwfl_begin() failed: %s\n", dwarf_errmsg(-1)); | ||
162 | return -1; | ||
163 | } | ||
164 | 160 | ||
165 | if (dwfl_report_offline(dwfl, "", exec_file, -1) == NULL) { | 161 | if (!dwfl) { |
166 | pr_debug("dwfl_report_offline() failed %s\n", dwarf_errmsg(-1)); | 162 | dwfl = dwfl_begin(&offline_callbacks); |
167 | goto out; | 163 | if (!dwfl) { |
164 | pr_debug("dwfl_begin() failed: %s\n", dwarf_errmsg(-1)); | ||
165 | return -1; | ||
166 | } | ||
167 | |||
168 | if (dwfl_report_offline(dwfl, "", dso->long_name, -1) == NULL) { | ||
169 | pr_debug("dwfl_report_offline() failed %s\n", | ||
170 | dwarf_errmsg(-1)); | ||
171 | /* | ||
172 | * We normally cache the DWARF debug info and never | ||
173 | * call dwfl_end(). But to prevent fd leak, free in | ||
174 | * case of error. | ||
175 | */ | ||
176 | dwfl_end(dwfl); | ||
177 | goto out; | ||
178 | } | ||
179 | dso->dwfl = dwfl; | ||
168 | } | 180 | } |
169 | 181 | ||
170 | mod = dwfl_addrmodule(dwfl, pc); | 182 | mod = dwfl_addrmodule(dwfl, pc); |
@@ -194,7 +206,6 @@ static int check_return_addr(const char *exec_file, Dwarf_Addr pc) | |||
194 | rc = check_return_reg(ra_regno, frame); | 206 | rc = check_return_reg(ra_regno, frame); |
195 | 207 | ||
196 | out: | 208 | out: |
197 | dwfl_end(dwfl); | ||
198 | return rc; | 209 | return rc; |
199 | } | 210 | } |
200 | 211 | ||
@@ -246,7 +257,7 @@ int arch_skip_callchain_idx(struct machine *machine, struct thread *thread, | |||
246 | return skip_slot; | 257 | return skip_slot; |
247 | } | 258 | } |
248 | 259 | ||
249 | rc = check_return_addr(dso->long_name, ip); | 260 | rc = check_return_addr(dso, ip); |
250 | 261 | ||
251 | pr_debug("DSO %s, nr %" PRIx64 ", ip 0x%" PRIx64 "rc %d\n", | 262 | pr_debug("DSO %s, nr %" PRIx64 ", ip 0x%" PRIx64 "rc %d\n", |
252 | dso->long_name, chain->nr, ip, rc); | 263 | dso->long_name, chain->nr, ip, rc); |
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index acb651acc7fd..3c9b391493f9 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h | |||
@@ -127,6 +127,7 @@ struct dso { | |||
127 | const char *long_name; | 127 | const char *long_name; |
128 | u16 long_name_len; | 128 | u16 long_name_len; |
129 | u16 short_name_len; | 129 | u16 short_name_len; |
130 | void *dwfl; /* DWARF debug info */ | ||
130 | 131 | ||
131 | /* dso data file */ | 132 | /* dso data file */ |
132 | struct { | 133 | struct { |