powerpc/perf: Adjust callchain based on DWARF debug info
PATCH v5 1/1 powerpc/perf: Adjust callchain based on DWARF debug info
[PATCH v5 1/1] powerpc/perf: Adjust callchain based on DWARF debug info
When saving the callchain on Power, the kernel conservatively saves excess entries in the callchain. A few of these entries are needed in some cases but not others. We should use the DWARF debug information to determine when the entries are needed.
Eg: the value in the link register (LR) is needed only when it holds the return address of a function. At other times it must be ignored.
If the unnecessary entries are not ignored, we end up with duplicate arcs in the call-graphs.
Use the DWARF debug information to determine if any callchain entries should be ignored when building call-graphs.
Callgraph before the patch:
14.67% 2234 sprintft libc-2.18.so [.] __random
|
--- __random
|
|--61.12%-- __random
| |
| |--97.15%-- rand
| | do_my_sprintf
| | main
| | generic_start_main.isra.0
| | __libc_start_main
| | 0x0
| |
| --2.85%-- do_my_sprintf
| main
| generic_start_main.isra.0
| __libc_start_main
| 0x0
|
--38.88%-- rand
|
|--94.01%-- rand
| do_my_sprintf
| main
| generic_start_main.isra.0
| __libc_start_main
| 0x0
|
--5.99%-- do_my_sprintf
main
generic_start_main.isra.0
__libc_start_main
0x0Callgraph after the patch:
14.67% 2234 sprintft libc-2.18.so [.] __random
|
--- __random
|
|--95.93%-- rand
| do_my_sprintf
| main
| generic_start_main.isra.0
| __libc_start_main
| 0x0
|
--4.07%-- do_my_sprintf
main
generic_start_main.isra.0
__libc_start_main
0x0TODO: For split-debug info objects like glibc, we can only determine
the call-frame-address only when both .eh_frame and .debug_info sections are available. We should be able to determin the CFA even without the .eh_frame section.
Fix suggested by Anton Blanchard.
Thanks to valuable input on DWARF debug information from Ulrich Weigand.
---
Changelog[v5]
[Jiri Olsa] Avoid the new external symbol PERF_CONTEXT_IGNORE; Revert back to previous version and use #ifdef directly in machine__resolve_callchain_sample() to avoid performance impact on other architectures.
Changelog[v4]
Move Powerpc-specific code into a separate patch
Changelog[v3]
[Jiri Olsa] Rename function to arch_skip_callchain_idx() to be
consistent with behavior.
[Jiri Olsa] Add '__maybe_unused' tags for unused parameters.
Changelog[v2]:
Add missing dwfl_end()
Fix merge conflicts due to some unwind code
tools/perf/arch/powerpc/Makefile | 1 + tools/perf/arch/powerpc/util/skip-callchain-idx.c | 266 +++++++++++++++++++++ tools/perf/config/Makefile | 4 + tools/perf/util/callchain.h | 13 + tools/perf/util/machine.c | 18 +- 5 files changed, 300 insertions(+), 2 deletions(-) create mode 100644 tools/perf/arch/powerpc/util/skip-callchain-idx.c
tools/perf/arch/powerpc/Makefile +1 -0
@@ -3,3 +3,4 @@ PERF_HAVE_DWARF_REGS := 1 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o endif LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/skip-callchain-idx.o
tools/perf/arch/powerpc/util/skip-callchain-idx.c new file +266 -0
266 lines not on this page · raw message
tools/perf/config/Makefile +4 -0
@@ -48,6 +48,10 @@ ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) NO_LIBDW_DWARF_UNWIND := 1 endif +ifeq ($(ARCH),powerpc) + CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX +endif + ifeq ($(LIBUNWIND_LIBS),) NO_LIBUNWIND := 1 else
tools/perf/util/callchain.h +13 -0
@@ -176,4 +176,17 @@ static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, dest->first = src->curr; dest->nr -= src->pos; } + +#ifdef HAVE_SKIP_CALLCHAIN_IDX +extern int arch_skip_callchain_idx (struct machine *machine, +struct thread *thread,struct ip_callchain *chain); +#else +static inline int arch_skip_callchain_idx (struct machine *machine__maybe_unused , +struct thread *thread__maybe_unused , +struct ip_callchain *chain__maybe_unused ) +{ +return -1 ; +} +#endif +#endif /* __PERF_CALLCHAIN_H */
tools/perf/util/machine.c +16 -2
@@ -1291,7 +1291,9 @@ static int machine__resolve_callchain_sample(struct machine *machine,u8 cpumode =PERF_RECORD_MISC_USER ;int chain_nr =min (max_stack, (int )chain->nr);int i; +int j;int err; +int skip_idx;callchain_cursor_reset (&callchain_cursor);
@@ -1300,14 +1302,26 @@ static int machine__resolve_callchain_sample(struct machine *machine,return 0 ; } +/* +* Based on DWARF debug information, some architectures skip +* a callchain entry saved by the kernel. +*/ + skip_idx =arch_skip_callchain_idx (machine, thread, chain); +for (i =0 ; i < chain_nr; i++) {u64 ip;struct addr_location al;if (callchain_param.order ==ORDER_CALLEE ) - ip = chain->ips[i]; + j = i;else - ip = chain->ips[chain->nr - i -1 ]; + j = chain->nr - i -1 ; + +#ifdef HAVE_SKIP_CALLCHAIN_IDX +if (j == skip_idx) +continue ; +#endif + ip = chain->ips[j];if (ip >=PERF_CONTEXT_MAX ) {switch (ip) {
Signature · 1 line
1.7.9.5
Quoted 1 line · Sukadev Bhattiprolu
[PATCH v5 1/1] powerpc/perf: Adjust callchain based on DWARF debug info
superflous ^^^
Quoted 5 lines
When saving the callchain on Power, the kernel conservatively saves excess entries in the callchain. A few of these entries are needed in some cases but not others. We should use the DWARF debug information to determine when the entries are needed.
SNIP
Quoted 46 lines
tools/perf/util/machine.c +16
-2@@ -1291,7 +1291,9 @@ static int machine__resolve_callchain_sample(struct machine *machine,u8 cpumode =PERF_RECORD_MISC_USER ;int chain_nr =min (max_stack, (int )chain->nr);int i; +int j;int err; +int skip_idx;callchain_cursor_reset (&callchain_cursor);@@ -1300,14 +1302,26 @@ static int machine__resolve_callchain_sample(struct machine *machine,return 0 ; } +/* +* Based on DWARF debug information, some architectures skip +* a callchain entry saved by the kernel. +*/ + skip_idx =arch_skip_callchain_idx (machine, thread, chain); +for (i =0 ; i < chain_nr; i++) {u64 ip;struct addr_location al;if (callchain_param.order ==ORDER_CALLEE ) - ip = chain->ips[i]; + j = i;else - ip = chain->ips[chain->nr - i -1 ]; + j = chain->nr - i -1 ; + +#ifdef HAVE_SKIP_CALLCHAIN_IDX +if (j == skip_idx) +continue ; +#endif + ip = chain->ips[j];if (ip >=PERF_CONTEXT_MAX ) {switch (ip) {Signature · 1 line
1.7.9.5
got following compile error:
CC util/map.outil/machine.c: In function ‘machine__resolve_callchain_sample’:util/machine.c:1286:6: error: variable ‘skip_idx’ set but not used [-Werror=unused-but-set-variable]
int skip_idx;
^cc1: all warnings being treated as errors make[2]: *** [util/machine.o] Error 1 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [all] Error 2
test: test -x ./perf
make: *** [make_pure] Error 1
you could use __maybe_unused for the 'skip_idx'
jirka
Sukadev Bhattiprolu
Tested-by Maynard JohnsonJiri Olsa [[email protected]] wrote:
|
| you could use __maybe_unused for the 'skip_idx'
Yes, here is the updated patch.
---
powerpc/perf: Adjust callchain based on DWARF debug info
When saving the callchain on Power, the kernel conservatively saves excess entries in the callchain. A few of these entries are needed in some cases but not others. We should use the DWARF debug information to determine when the entries are needed.
Eg: the value in the link register (LR) is needed only when it holds the return address of a function. At other times it must be ignored.
If the unnecessary entries are not ignored, we end up with duplicate arcs in the call-graphs.
Use the DWARF debug information to determine if any callchain entries should be ignored when building call-graphs.
Callgraph before the patch:
14.67% 2234 sprintft libc-2.18.so [.] __random
|
--- __random
|
|--61.12%-- __random
| |
| |--97.15%-- rand
| | do_my_sprintf
| | main
| | generic_start_main.isra.0
| | __libc_start_main
| | 0x0
| |
| --2.85%-- do_my_sprintf
| main
| generic_start_main.isra.0
| __libc_start_main
| 0x0
|
--38.88%-- rand
|
|--94.01%-- rand
| do_my_sprintf
| main
| generic_start_main.isra.0
| __libc_start_main
| 0x0
|
--5.99%-- do_my_sprintf
main
generic_start_main.isra.0
__libc_start_main
0x0Callgraph after the patch:
14.67% 2234 sprintft libc-2.18.so [.] __random
|
--- __random
|
|--95.93%-- rand
| do_my_sprintf
| main
| generic_start_main.isra.0
| __libc_start_main
| 0x0
|
--4.07%-- do_my_sprintf
main
generic_start_main.isra.0
__libc_start_main
0x0TODO: For split-debug info objects like glibc, we can only determine
the call-frame-address only when both .eh_frame and .debug_info sections are available. We should be able to determin the CFA even without the .eh_frame section.
Fix suggested by Anton Blanchard.
Thanks to valuable input on DWARF debug information from Ulrich Weigand.
Changelog[v5]
[Jiri Olsa] Avoid the new external symbol PERF_CONTEXT_IGNORE; Revert back to previous version and to avoid impact on other architectures, use #ifdef in machine__resolve_callchain_sample().
Changelog[v4]
Move Powerpc-specific code into a separate patch
Changelog[v3]
[Jiri Olsa] Rename function to arch_skip_callchain_idx() to be
consistent with behavior.
[Jiri Olsa] Add '__maybe_unused' tags for unused parameters.
Changelog[v2]:
Add missing dwfl_end()
Fix merge conflicts due to some unwind code
--- tools/perf/arch/powerpc/Makefile | 1 + tools/perf/arch/powerpc/util/skip-callchain-idx.c | 266 +++++++++++++++++++++ tools/perf/config/Makefile | 4 + tools/perf/util/callchain.h | 13 + tools/perf/util/machine.c | 18 +- 5 files changed, 300 insertions(+), 2 deletions(-) create mode 100644 tools/perf/arch/powerpc/util/skip-callchain-idx.c
tools/perf/arch/powerpc/Makefile +1 -0
@@ -3,3 +3,4 @@ PERF_HAVE_DWARF_REGS := 1 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o endif LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/skip-callchain-idx.o
tools/perf/arch/powerpc/util/skip-callchain-idx.c new file +266 -0
266 lines not on this page · raw message
tools/perf/config/Makefile +4 -0
@@ -48,6 +48,10 @@ ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) NO_LIBDW_DWARF_UNWIND := 1 endif +ifeq ($(ARCH),powerpc) + CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX +endif + ifeq ($(LIBUNWIND_LIBS),) NO_LIBUNWIND := 1 else
tools/perf/util/callchain.h +13 -0
@@ -176,4 +176,17 @@ static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, dest->first = src->curr; dest->nr -= src->pos; } + +#ifdef HAVE_SKIP_CALLCHAIN_IDX +extern int arch_skip_callchain_idx (struct machine *machine, +struct thread *thread,struct ip_callchain *chain); +#else +static inline int arch_skip_callchain_idx (struct machine *machine__maybe_unused , +struct thread *thread__maybe_unused , +struct ip_callchain *chain__maybe_unused ) +{ +return -1 ; +} +#endif +#endif /* __PERF_CALLCHAIN_H */
tools/perf/util/machine.c +16 -2
@@ -1291,7 +1291,9 @@ static int machine__resolve_callchain_sample(struct machine *machine,u8 cpumode =PERF_RECORD_MISC_USER ;int chain_nr =min (max_stack, (int )chain->nr);int i; +int j;int err; +int skip_idx__maybe_unused ;callchain_cursor_reset (&callchain_cursor);
@@ -1300,14 +1302,26 @@ static int machine__resolve_callchain_sample(struct machine *machine,return 0 ; } +/* +* Based on DWARF debug information, some architectures skip +* a callchain entry saved by the kernel. +*/ + skip_idx =arch_skip_callchain_idx (machine, thread, chain); +for (i =0 ; i < chain_nr; i++) {u64 ip;struct addr_location al;if (callchain_param.order ==ORDER_CALLEE ) - ip = chain->ips[i]; + j = i;else - ip = chain->ips[chain->nr - i -1 ]; + j = chain->nr - i -1 ; + +#ifdef HAVE_SKIP_CALLCHAIN_IDX +if (j == skip_idx) +continue ; +#endif + ip = chain->ips[j];if (ip >=PERF_CONTEXT_MAX ) {switch (ip) {
Signature · 1 line
1.7.9.5
tip-bot for Sukadev Bhattiprolu
merge bot[tip:perf/core] perf tools powerpc: Adjust callchain based on DWARF debug info
perf tools powerpc: Adjust callchain based on DWARF debug info
Commit-ID: a60335ba32981db5bc057b35782644e9e2436407 Gitweb: http://git.kernel.org/tip/a60335ba32981db5bc057b35782644e9e2436407 Author: Sukadev Bhattiprolu <[email protected]> AuthorDate: Wed, 25 Jun 2014 08:49:03 -0700 Committer: Jiri Olsa <[email protected]> CommitDate: Fri, 27 Jun 2014 11:14:51 +0200
perf tools powerpc: Adjust callchain based on DWARF debug info
When saving the callchain on Power, the kernel conservatively saves excess entries in the callchain. A few of these entries are needed in some cases but not others. We should use the DWARF debug information to determine when the entries are needed.
Eg: the value in the link register (LR) is needed only when it holds the return address of a function. At other times it must be ignored.
If the unnecessary entries are not ignored, we end up with duplicate arcs in the call-graphs.
Use the DWARF debug information to determine if any callchain entries should be ignored when building call-graphs.
Callgraph before the patch:
14.67% 2234 sprintft libc-2.18.so [.] __random
|
--- __random
|
|--61.12%-- __random
| |
| |--97.15%-- rand
| | do_my_sprintf
| | main
| | generic_start_main.isra.0
| | __libc_start_main
| | 0x0
| |
| --2.85%-- do_my_sprintf
| main
| generic_start_main.isra.0
| __libc_start_main
| 0x0
|
--38.88%-- rand
|
|--94.01%-- rand
| do_my_sprintf
| main
| generic_start_main.isra.0
| __libc_start_main
| 0x0
|
--5.99%-- do_my_sprintf
main
generic_start_main.isra.0
__libc_start_main
0x0Callgraph after the patch:
14.67% 2234 sprintft libc-2.18.so [.] __random
|
--- __random
|
|--95.93%-- rand
| do_my_sprintf
| main
| generic_start_main.isra.0
| __libc_start_main
| 0x0
|
--4.07%-- do_my_sprintf
main
generic_start_main.isra.0
__libc_start_main
0x0TODO: For split-debug info objects like glibc, we can only determine
the call-frame-address only when both .eh_frame and .debug_info sections are available. We should be able to determin the CFA even without the .eh_frame section.
Fix suggested by Anton Blanchard.
Thanks to valuable input on DWARF debug information from Ulrich Weigand.
--- tools/perf/arch/powerpc/Makefile | 1 + tools/perf/arch/powerpc/util/skip-callchain-idx.c | 266 ++++++++++++++++++++++ tools/perf/config/Makefile | 4 + tools/perf/util/callchain.h | 13 ++ tools/perf/util/machine.c | 18 +- 5 files changed, 300 insertions(+), 2 deletions(-)
tools/perf/arch/powerpc/Makefile +1 -0
@@ -3,3 +3,4 @@ PERF_HAVE_DWARF_REGS := 1 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o endif LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/skip-callchain-idx.o
tools/perf/arch/powerpc/util/skip-callchain-idx.c new file +266 -0
266 lines not on this page · raw message
tools/perf/config/Makefile +4 -0
@@ -48,6 +48,10 @@ ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) NO_LIBDW_DWARF_UNWIND := 1 endif +ifeq ($(ARCH),powerpc) + CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX +endif + ifeq ($(LIBUNWIND_LIBS),) NO_LIBUNWIND := 1 else
tools/perf/util/callchain.h +13 -0
@@ -176,4 +176,17 @@ static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, dest->first = src->curr; dest->nr -= src->pos; } + +#ifdef HAVE_SKIP_CALLCHAIN_IDX +extern int arch_skip_callchain_idx (struct machine *machine, +struct thread *thread,struct ip_callchain *chain); +#else +static inline int arch_skip_callchain_idx (struct machine *machine__maybe_unused , +struct thread *thread__maybe_unused , +struct ip_callchain *chain__maybe_unused ) +{ +return -1 ; +} +#endif +#endif /* __PERF_CALLCHAIN_H */
tools/perf/util/machine.c +16 -2
@@ -1281,7 +1281,9 @@ static int machine__resolve_callchain_sample(struct machine *machine,u8 cpumode =PERF_RECORD_MISC_USER ;int chain_nr =min (max_stack, (int )chain->nr);int i; +int j;int err; +int skip_idx__maybe_unused ;callchain_cursor_reset (&callchain_cursor);
@@ -1290,14 +1292,26 @@ static int machine__resolve_callchain_sample(struct machine *machine,return 0 ; } +/* +* Based on DWARF debug information, some architectures skip +* a callchain entry saved by the kernel. +*/ + skip_idx =arch_skip_callchain_idx (machine, thread, chain); +for (i =0 ; i < chain_nr; i++) {u64 ip;struct addr_location al;if (callchain_param.order ==ORDER_CALLEE ) - ip = chain->ips[i]; + j = i;else - ip = chain->ips[chain->nr - i -1 ]; + j = chain->nr - i -1 ; + +#ifdef HAVE_SKIP_CALLCHAIN_IDX +if (j == skip_idx) +continue ; +#endif + ip = chain->ips[j];if (ip >=PERF_CONTEXT_MAX ) {switch (ip) {
Hi,
Quoted 6 lines · Sukadev Bhattiprolu
powerpc/perf: Adjust callchain based on DWARF debug info
When saving the callchain on Power, the kernel conservatively saves excess entries in the callchain. A few of these entries are needed in some cases but not others. We should use the DWARF debug information to determine when the entries are needed.
This patch breaks perf compilation if DWARF support is not present. DWARF support is auto-detected early in the build, so IMHO either user should be informed to install the needed stuff, or the build should succeed with limited functionality.
arch/powerpc/util/skip-callchain-idx.c:13:19: fatal error: dwarf.h: No such file or directory #include <dwarf.h>
^
compilation terminated.
A.
Quoted 10 lines · Aaro Koskinen
Hi,
Quoted 6 lines · Sukadev Bhattiprolu
powerpc/perf: Adjust callchain based on DWARF debug info
When saving the callchain on Power, the kernel conservatively saves excess entries in the callchain. A few of these entries are needed in some cases but not others. We should use the DWARF debug information to determine when the entries are needed.
Quoted 8 lines
This patch breaks perf compilation if DWARF support is not present. DWARF support is auto-detected early in the build, so IMHO either user should be informed to install the needed stuff, or the build should succeed with limited functionality.
arch/powerpc/util/skip-callchain-idx.c:13:19: fatal error:dwarf.h: No such file or directory #include <dwarf.h>^compilation terminated.
looks like powerpc issue.. hows 'make -f tests/make' doing on powerpc? It tests above scenario.
jirka
Aaro Koskinen [[email protected]] wrote:
| Hi, | | On Wed, Jun 25, 2014 at 08:49:03AM -0700, Sukadev Bhattiprolu wrote: | > powerpc/perf: Adjust callchain based on DWARF debug info | > | > When saving the callchain on Power, the kernel conservatively saves excess | > entries in the callchain. A few of these entries are needed in some cases | > but not others. We should use the DWARF debug information to determine | > when the entries are needed. | | This patch breaks perf compilation if DWARF support is not present. | DWARF support is auto-detected early in the build, so IMHO either user | should be informed to install the needed stuff, or the build should | succeed with limited functionality. | | arch/powerpc/util/skip-callchain-idx.c:13:19: fatal error: dwarf.h: No such file or directory #include <dwarf.h> | ^ | compilation terminated.
Yes. Sorry. Anton fixed this recently:
https://lkml.org/lkml/2014/9/19/29
Sukadev