kernel_optimize_test/arch
Frederic Weisbecker b625b3b3b7 x86: Fixup wrong debug exception frame link in stacktraces
While dumping a stacktrace, the end of the exception stack won't link
the frame pointer to the previous stack.

The interrupted stack will then be considered as unreliable and ignored
by perf, as the frame pointer is unreliable itself.

This happens because we overwrite the frame pointer that links to the
interrupted frame with the address of the exception stack. This is
done in order to reserve space inside.
But rbp has been chosen here only because it is not a scratch register,
so that the address of the exception stack remains in rbp after calling
do_debug(), we can then release the exception stack space without the
need to retrieve its address again.

But we can pick another non-scratch register to do that, so that we
preserve the link to the interrupted stack frame in the stacktraces.

Just randomly choose r12. Every registers are saved just before and
restored just after calling do_debug(). And r12 is not used in the
middle, which makes it a perfect candidate.

Example: perf record -g -a -c 1 -f -e mem:$(tasklist_lock_addr):rw

Before:
    44.18%  [k] _raw_read_lock
            |
            |
            ---  |--6.31%-- waitid
                 |
                 |--4.26%-- writev
                 |
                 |--3.63%-- __select
                 |
                 |--3.15%-- __waitpid
                 |          |
                 |          |--28.57%-- 0x8b52e00000139f
                 |          |
                 |          |--28.57%-- 0x8b52e0000013c6
                 |          |
                 |          |--14.29%-- 0x7fde786dc000
                 |          |
                 |          |--14.29%-- 0x62696c2f7273752f
                 |          |
                 |           --14.29%-- 0x1ea9df800000000
                 |
                 |--3.00%-- __poll

After:

    43.94%  [k] _raw_read_lock
            |
            --- _read_lock
               |
               |--60.53%-- send_sigio
               |          __kill_fasync
               |          kill_fasync
               |          evdev_pass_event
               |          evdev_event
               |          input_pass_event
               |          input_handle_event
               |          input_event
               |          synaptics_process_byte
               |          psmouse_handle_byte
               |          psmouse_interrupt
               |          serio_interrupt
               |          i8042_interrupt
               |          handle_IRQ_event
               |          handle_edge_irq
               |          handle_irq
               |          __irqentry_text_start
               |          ret_from_intr
               |          |
               |          |--30.43%-- __select
               |          |
               |          |--17.39%-- 0x454f15
               |          |
               |          |--13.04%-- __read
               |          |
               |          |--13.04%-- vread_hpet
               |          |
               |          |--13.04%-- _xcb_lock_io
               |          |
               |           --13.04%-- 0x7f630878ce87

Note: it does not only affect perf events but also other stacktraces in
x86-64. They were considered as unreliable once we quit the debug
stack frame.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: "K. Prasad" <prasad@linux.vnet.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
2009-12-06 08:27:22 +01:00
..
alpha alpha: move THREAD_SIZE definition outside #ifndef ASSEMBLY 2009-11-12 07:25:56 -08:00
arm Merge branch 'omap-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6 2009-11-12 14:57:15 -08:00
avr32 at91: at91sam9g45 family: identify several chip versions 2009-11-03 18:42:31 +01:00
blackfin headers: remove sched.h from interrupt.h 2009-10-11 11:20:58 -07:00
cris const: constify remaining file_operations 2009-10-01 16:11:11 -07:00
frv frv: fix check on unsigned in do_signal() 2009-10-29 07:39:32 -07:00
h8300 h8300: Cleanup linker script using new linker script macros. 2009-09-24 17:16:22 -07:00
ia64 Revert "[IA64] fix percpu warnings" 2009-11-02 09:23:08 -08:00
m32r m32r: fix arch/m32r/boot/compressed/Makefile 2009-11-09 09:00:50 +09:00
m68k tty: Mark generic_serial users as BROKEN 2009-10-30 14:43:12 -07:00
m68knommu m68knommu: fix rename of pt_regs offset defines breakage 2009-09-30 10:06:07 +10:00
microblaze microblaze: Clear sticky FSR register after saving it to func parametr 2009-10-05 11:37:47 +02:00
mips MIPS: O32: Fix ppoll 2009-11-02 12:00:08 +01:00
mn10300 mn10300: fix kernel build failures when using gcc-4.x 2009-10-01 16:11:12 -07:00
parisc parisc: Fix linker script breakage. 2009-09-28 00:25:07 -04:00
powerpc Merge branches 'perf/powerpc' and 'perf/bench' into perf/core 2009-11-15 09:51:24 +01:00
s390 Merge commit 'v2.6.32-rc6' into perf/core 2009-11-04 11:59:45 +01:00
score Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next 2009-09-23 15:37:02 -07:00
sh sh: Replace old style lock initializer 2009-11-09 10:47:40 +09:00
sparc sparc: Move of_set_property_mutex acquisition outside of devtree_lock grab. 2009-11-08 17:41:20 -08:00
um headers: remove sched.h from interrupt.h 2009-10-11 11:20:58 -07:00
x86 x86: Fixup wrong debug exception frame link in stacktraces 2009-12-06 08:27:22 +01:00
xtensa headers: remove sched.h from interrupt.h 2009-10-11 11:20:58 -07:00
.gitignore
Kconfig hw-breakpoints: Rewrite the hw-breakpoints layer on top of perf events 2009-11-08 15:34:42 +01:00