diff options
author | Namhyung Kim <namhyung@kernel.org> | 2014-10-05 20:46:01 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-10-29 08:25:22 -0400 |
commit | 380b5143ab76de71572c7a30e68c8e22b94bee52 (patch) | |
tree | 52f0dc23a6586d4545c5f92464320adbc8b14ae6 | |
parent | 1776b10627e486dd431fe72d8d47e5a865cf65d1 (diff) |
perf callchain: Use global caching provided by libunwind
The libunwind provides two caching policy which are global and
per-thread. As perf unwinds callchains in a single thread, it'd
sufficient to use global caching.
This speeds up my perf report from 14s to 7s on a ~260MB data file.
Although the output sometimes contains a slight difference (~0.01% in
terms of number of lines printed) on callchains which were not resolved.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jean Pihet <jean.pihet@linaro.org>
Cc: Arun Sharma <asharma@fb.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: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1412556363-26229-4-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/thread.c | 3 | ||||
-rw-r--r-- | tools/perf/util/unwind-libunwind.c | 12 | ||||
-rw-r--r-- | tools/perf/util/unwind.h | 3 |
3 files changed, 18 insertions, 0 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 2b7b2d91c016..c41411726c7a 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -117,6 +117,9 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, | |||
117 | if (!new) | 117 | if (!new) |
118 | return -ENOMEM; | 118 | return -ENOMEM; |
119 | list_add(&new->list, &thread->comm_list); | 119 | list_add(&new->list, &thread->comm_list); |
120 | |||
121 | if (exec) | ||
122 | unwind__flush_access(thread); | ||
120 | } | 123 | } |
121 | 124 | ||
122 | thread->comm_set = true; | 125 | thread->comm_set = true; |
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index e060386165c5..4d45c0dfe343 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c | |||
@@ -539,11 +539,23 @@ int unwind__prepare_access(struct thread *thread) | |||
539 | return -ENOMEM; | 539 | return -ENOMEM; |
540 | } | 540 | } |
541 | 541 | ||
542 | unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL); | ||
542 | thread__set_priv(thread, addr_space); | 543 | thread__set_priv(thread, addr_space); |
543 | 544 | ||
544 | return 0; | 545 | return 0; |
545 | } | 546 | } |
546 | 547 | ||
548 | void unwind__flush_access(struct thread *thread) | ||
549 | { | ||
550 | unw_addr_space_t addr_space; | ||
551 | |||
552 | if (callchain_param.record_mode != CALLCHAIN_DWARF) | ||
553 | return; | ||
554 | |||
555 | addr_space = thread__priv(thread); | ||
556 | unw_flush_cache(addr_space, 0, 0); | ||
557 | } | ||
558 | |||
547 | void unwind__finish_access(struct thread *thread) | 559 | void unwind__finish_access(struct thread *thread) |
548 | { | 560 | { |
549 | unw_addr_space_t addr_space; | 561 | unw_addr_space_t addr_space; |
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index c17c4855bdbc..f50b737235eb 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h | |||
@@ -23,6 +23,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, | |||
23 | #ifdef HAVE_LIBUNWIND_SUPPORT | 23 | #ifdef HAVE_LIBUNWIND_SUPPORT |
24 | int libunwind__arch_reg_id(int regnum); | 24 | int libunwind__arch_reg_id(int regnum); |
25 | int unwind__prepare_access(struct thread *thread); | 25 | int unwind__prepare_access(struct thread *thread); |
26 | void unwind__flush_access(struct thread *thread); | ||
26 | void unwind__finish_access(struct thread *thread); | 27 | void unwind__finish_access(struct thread *thread); |
27 | #else | 28 | #else |
28 | static inline int unwind__prepare_access(struct thread *thread __maybe_unused) | 29 | static inline int unwind__prepare_access(struct thread *thread __maybe_unused) |
@@ -30,6 +31,7 @@ static inline int unwind__prepare_access(struct thread *thread __maybe_unused) | |||
30 | return 0; | 31 | return 0; |
31 | } | 32 | } |
32 | 33 | ||
34 | static inline void unwind__flush_access(struct thread *thread __maybe_unused) {} | ||
33 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} | 35 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} |
34 | #endif | 36 | #endif |
35 | #else | 37 | #else |
@@ -49,6 +51,7 @@ static inline int unwind__prepare_access(struct thread *thread __maybe_unused) | |||
49 | return 0; | 51 | return 0; |
50 | } | 52 | } |
51 | 53 | ||
54 | static inline void unwind__flush_access(struct thread *thread __maybe_unused) {} | ||
52 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} | 55 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} |
53 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ | 56 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ |
54 | #endif /* __UNWIND_H */ | 57 | #endif /* __UNWIND_H */ |