diff options
author | Jiri Olsa <jolsa@kernel.org> | 2014-04-30 09:47:27 -0400 |
---|---|---|
committer | Jiri Olsa <jolsa@kernel.org> | 2014-06-12 10:53:20 -0400 |
commit | c658045197814b7d762662f9aa9f652379121a03 (patch) | |
tree | 4f61850960139bbf9382480c32a4247f8a907ab1 | |
parent | bda6ee4a94d1e1be0c1428d37bc0d3da2e5793ad (diff) |
perf tools: Cache dso data file descriptor
Caching dso data file descriptors to avoid expensive re-opens
especially during DWARF unwind.
We keep dsos data file descriptors open until their count reaches
the half of the current fd open limit (RLIMIT_NOFILE). In this case
we close file descriptor of the first opened dso object.
We've got overall speedup (~27% for my workload) of report:
'perf report --stdio -i perf-test.data' (3 runs)
(perf-test.data size was around 12GB)
current code:
545,640,944,228 cycles ( +- 0.53% )
785,255,798,320 instructions ( +- 0.03% )
366.340910010 seconds time elapsed ( +- 3.65% )
after change:
435,895,036,114 cycles ( +- 0.26% )
636,790,271,176 instructions ( +- 0.04% )
266.481463387 seconds time elapsed ( +- 0.13% )
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1401892622-30848-7-git-send-email-jolsa@kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
-rw-r--r-- | tools/perf/util/dso.c | 61 | ||||
-rw-r--r-- | tools/perf/util/unwind-libunwind.c | 2 |
2 files changed, 59 insertions, 4 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 76e5c13afc8f..fbf6cc98b8a9 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
@@ -1,4 +1,6 @@ | |||
1 | #include <asm/bug.h> | 1 | #include <asm/bug.h> |
2 | #include <sys/time.h> | ||
3 | #include <sys/resource.h> | ||
2 | #include "symbol.h" | 4 | #include "symbol.h" |
3 | #include "dso.h" | 5 | #include "dso.h" |
4 | #include "machine.h" | 6 | #include "machine.h" |
@@ -180,12 +182,20 @@ static int __open_dso(struct dso *dso, struct machine *machine) | |||
180 | return fd; | 182 | return fd; |
181 | } | 183 | } |
182 | 184 | ||
185 | static void check_data_close(void); | ||
186 | |||
183 | static int open_dso(struct dso *dso, struct machine *machine) | 187 | static int open_dso(struct dso *dso, struct machine *machine) |
184 | { | 188 | { |
185 | int fd = __open_dso(dso, machine); | 189 | int fd = __open_dso(dso, machine); |
186 | 190 | ||
187 | if (fd > 0) | 191 | if (fd > 0) { |
188 | dso__list_add(dso); | 192 | dso__list_add(dso); |
193 | /* | ||
194 | * Check if we crossed the allowed number | ||
195 | * of opened DSOs and close one if needed. | ||
196 | */ | ||
197 | check_data_close(); | ||
198 | } | ||
189 | 199 | ||
190 | return fd; | 200 | return fd; |
191 | } | 201 | } |
@@ -204,6 +214,54 @@ static void close_dso(struct dso *dso) | |||
204 | close_data_fd(dso); | 214 | close_data_fd(dso); |
205 | } | 215 | } |
206 | 216 | ||
217 | static void close_first_dso(void) | ||
218 | { | ||
219 | struct dso *dso; | ||
220 | |||
221 | dso = list_first_entry(&dso__data_open, struct dso, data.open_entry); | ||
222 | close_dso(dso); | ||
223 | } | ||
224 | |||
225 | static rlim_t get_fd_limit(void) | ||
226 | { | ||
227 | struct rlimit l; | ||
228 | rlim_t limit = 0; | ||
229 | |||
230 | /* Allow half of the current open fd limit. */ | ||
231 | if (getrlimit(RLIMIT_NOFILE, &l) == 0) { | ||
232 | if (l.rlim_cur == RLIM_INFINITY) | ||
233 | limit = l.rlim_cur; | ||
234 | else | ||
235 | limit = l.rlim_cur / 2; | ||
236 | } else { | ||
237 | pr_err("failed to get fd limit\n"); | ||
238 | limit = 1; | ||
239 | } | ||
240 | |||
241 | return limit; | ||
242 | } | ||
243 | |||
244 | static bool may_cache_fd(void) | ||
245 | { | ||
246 | static rlim_t limit; | ||
247 | |||
248 | if (!limit) | ||
249 | limit = get_fd_limit(); | ||
250 | |||
251 | if (limit == RLIM_INFINITY) | ||
252 | return true; | ||
253 | |||
254 | return limit > (rlim_t) dso__data_open_cnt; | ||
255 | } | ||
256 | |||
257 | static void check_data_close(void) | ||
258 | { | ||
259 | bool cache_fd = may_cache_fd(); | ||
260 | |||
261 | if (!cache_fd) | ||
262 | close_first_dso(); | ||
263 | } | ||
264 | |||
207 | void dso__data_close(struct dso *dso) | 265 | void dso__data_close(struct dso *dso) |
208 | { | 266 | { |
209 | close_dso(dso); | 267 | close_dso(dso); |
@@ -356,7 +414,6 @@ dso_cache__read(struct dso *dso, struct machine *machine, | |||
356 | if (ret <= 0) | 414 | if (ret <= 0) |
357 | free(cache); | 415 | free(cache); |
358 | 416 | ||
359 | dso__data_close(dso); | ||
360 | return ret; | 417 | return ret; |
361 | } | 418 | } |
362 | 419 | ||
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 4f8dd9ee3899..25578b98f5c5 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c | |||
@@ -250,7 +250,6 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine, | |||
250 | 250 | ||
251 | /* Check the .eh_frame section for unwinding info */ | 251 | /* Check the .eh_frame section for unwinding info */ |
252 | offset = elf_section_offset(fd, ".eh_frame_hdr"); | 252 | offset = elf_section_offset(fd, ".eh_frame_hdr"); |
253 | dso__data_close(dso); | ||
254 | 253 | ||
255 | if (offset) | 254 | if (offset) |
256 | ret = unwind_spec_ehframe(dso, machine, offset, | 255 | ret = unwind_spec_ehframe(dso, machine, offset, |
@@ -271,7 +270,6 @@ static int read_unwind_spec_debug_frame(struct dso *dso, | |||
271 | 270 | ||
272 | /* Check the .debug_frame section for unwinding info */ | 271 | /* Check the .debug_frame section for unwinding info */ |
273 | *offset = elf_section_offset(fd, ".debug_frame"); | 272 | *offset = elf_section_offset(fd, ".debug_frame"); |
274 | dso__data_close(dso); | ||
275 | 273 | ||
276 | if (*offset) | 274 | if (*offset) |
277 | return 0; | 275 | return 0; |