Skip to content

Commit

Permalink
Merge branch 'ftrace' of git://github.com/rabinv/linux-2.6 into devel…
Browse files Browse the repository at this point in the history
…-stable
  • Loading branch information
Russell King committed Nov 26, 2010
2 parents f1690d1 + 0e341af commit 83cf1ee
Show file tree
Hide file tree
Showing 11 changed files with 273 additions and 77 deletions.
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ config ARM
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL)
select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
select HAVE_GENERIC_DMA_COHERENT
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_LZO
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ config STRICT_DEVMEM
config FRAME_POINTER
bool
depends on !THUMB2_KERNEL
default y if !ARM_UNWIND
default y if !ARM_UNWIND || FUNCTION_GRAPH_TRACER
help
If you say N here, the resulting kernel will be slightly smaller and
faster. However, if neither FRAME_POINTER nor ARM_UNWIND are enabled,
Expand Down
5 changes: 5 additions & 0 deletions arch/arm/include/asm/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
#include <asm/outercache.h>

#define __exception __attribute__((section(".exception.text")))
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#define __exception_irq_entry __irq_entry
#else
#define __exception_irq_entry __exception
#endif

struct thread_info;
struct task_struct;
Expand Down
23 changes: 21 additions & 2 deletions arch/arm/include/asm/traps.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,32 @@ struct undef_hook {
void register_undef_hook(struct undef_hook *hook);
void unregister_undef_hook(struct undef_hook *hook);

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
static inline int __in_irqentry_text(unsigned long ptr)
{
extern char __irqentry_text_start[];
extern char __irqentry_text_end[];

return ptr >= (unsigned long)&__irqentry_text_start &&
ptr < (unsigned long)&__irqentry_text_end;
}
#else
static inline int __in_irqentry_text(unsigned long ptr)
{
return 0;
}
#endif

static inline int in_exception_text(unsigned long ptr)
{
extern char __exception_text_start[];
extern char __exception_text_end[];
int in;

in = ptr >= (unsigned long)&__exception_text_start &&
ptr < (unsigned long)&__exception_text_end;

return ptr >= (unsigned long)&__exception_text_start &&
ptr < (unsigned long)&__exception_text_end;
return in ? : __in_irqentry_text(ptr);
}

extern void __init early_trap_init(void);
Expand Down
3 changes: 2 additions & 1 deletion arch/arm/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)

ifdef CONFIG_DYNAMIC_FTRACE
ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_ftrace.o = -pg
endif

Expand Down Expand Up @@ -33,6 +33,7 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o
obj-$(CONFIG_ATAGS_PROC) += atags.o
Expand Down
202 changes: 137 additions & 65 deletions arch/arm/kernel/entry-common.S
Original file line number Diff line number Diff line change
Expand Up @@ -141,98 +141,170 @@ ENDPROC(ret_from_fork)
#endif
#endif

#ifdef CONFIG_DYNAMIC_FTRACE
ENTRY(__gnu_mcount_nc)
mov ip, lr
ldmia sp!, {lr}
mov pc, ip
ENDPROC(__gnu_mcount_nc)
.macro __mcount suffix
mcount_enter
ldr r0, =ftrace_trace_function
ldr r2, [r0]
adr r0, .Lftrace_stub
cmp r0, r2
bne 1f

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
ldr r1, =ftrace_graph_return
ldr r2, [r1]
cmp r0, r2
bne ftrace_graph_caller\suffix

ldr r1, =ftrace_graph_entry
ldr r2, [r1]
ldr r0, =ftrace_graph_entry_stub
cmp r0, r2
bne ftrace_graph_caller\suffix
#endif

ENTRY(ftrace_caller)
stmdb sp!, {r0-r3, lr}
mov r0, lr
mcount_exit

1: mcount_get_lr r1 @ lr of instrumented func
mov r0, lr @ instrumented function
sub r0, r0, #MCOUNT_INSN_SIZE
adr lr, BSYM(2f)
mov pc, r2
2: mcount_exit
.endm

.macro __ftrace_caller suffix
mcount_enter

mcount_get_lr r1 @ lr of instrumented func
mov r0, lr @ instrumented function
sub r0, r0, #MCOUNT_INSN_SIZE
ldr r1, [sp, #20]

.global ftrace_call
ftrace_call:
.globl ftrace_call\suffix
ftrace_call\suffix:
bl ftrace_stub
ldmia sp!, {r0-r3, ip, lr}
mov pc, ip
ENDPROC(ftrace_caller)

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_call\suffix
ftrace_graph_call\suffix:
mov r0, r0
#endif

mcount_exit
.endm

.macro __ftrace_graph_caller
sub r0, fp, #4 @ &lr of instrumented routine (&parent)
#ifdef CONFIG_DYNAMIC_FTRACE
@ called from __ftrace_caller, saved in mcount_enter
ldr r1, [sp, #16] @ instrumented routine (func)
#else
@ called from __mcount, untouched in lr
mov r1, lr @ instrumented routine (func)
#endif
sub r1, r1, #MCOUNT_INSN_SIZE
mov r2, fp @ frame pointer
bl prepare_ftrace_return
mcount_exit
.endm

#ifdef CONFIG_OLD_MCOUNT
/*
* mcount
*/

.macro mcount_enter
stmdb sp!, {r0-r3, lr}
.endm

.macro mcount_get_lr reg
ldr \reg, [fp, #-4]
.endm

.macro mcount_exit
ldr lr, [fp, #-4]
ldmia sp!, {r0-r3, pc}
.endm

ENTRY(mcount)
#ifdef CONFIG_DYNAMIC_FTRACE
stmdb sp!, {lr}
ldr lr, [fp, #-4]
ldmia sp!, {pc}
#else
__mcount _old
#endif
ENDPROC(mcount)

#ifdef CONFIG_DYNAMIC_FTRACE
ENTRY(ftrace_caller_old)
stmdb sp!, {r0-r3, lr}
ldr r1, [fp, #-4]
mov r0, lr
sub r0, r0, #MCOUNT_INSN_SIZE

.globl ftrace_call_old
ftrace_call_old:
bl ftrace_stub
ldr lr, [fp, #-4] @ restore lr
ldmia sp!, {r0-r3, pc}
__ftrace_caller _old
ENDPROC(ftrace_caller_old)
#endif

#else
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
ENTRY(ftrace_graph_caller_old)
__ftrace_graph_caller
ENDPROC(ftrace_graph_caller_old)
#endif

ENTRY(__gnu_mcount_nc)
.purgem mcount_enter
.purgem mcount_get_lr
.purgem mcount_exit
#endif

/*
* __gnu_mcount_nc
*/

.macro mcount_enter
stmdb sp!, {r0-r3, lr}
ldr r0, =ftrace_trace_function
ldr r2, [r0]
adr r0, .Lftrace_stub
cmp r0, r2
bne gnu_trace
.endm

.macro mcount_get_lr reg
ldr \reg, [sp, #20]
.endm

.macro mcount_exit
ldmia sp!, {r0-r3, ip, lr}
mov pc, ip
.endm

gnu_trace:
ldr r1, [sp, #20] @ lr of instrumented routine
mov r0, lr
sub r0, r0, #MCOUNT_INSN_SIZE
adr lr, BSYM(1f)
mov pc, r2
1:
ldmia sp!, {r0-r3, ip, lr}
ENTRY(__gnu_mcount_nc)
#ifdef CONFIG_DYNAMIC_FTRACE
mov ip, lr
ldmia sp!, {lr}
mov pc, ip
#else
__mcount
#endif
ENDPROC(__gnu_mcount_nc)

#ifdef CONFIG_OLD_MCOUNT
/*
* This is under an ifdef in order to force link-time errors for people trying
* to build with !FRAME_POINTER with a GCC which doesn't use the new-style
* mcount.
*/
ENTRY(mcount)
stmdb sp!, {r0-r3, lr}
ldr r0, =ftrace_trace_function
ldr r2, [r0]
adr r0, ftrace_stub
cmp r0, r2
bne trace
ldr lr, [fp, #-4] @ restore lr
ldmia sp!, {r0-r3, pc}
#ifdef CONFIG_DYNAMIC_FTRACE
ENTRY(ftrace_caller)
__ftrace_caller
ENDPROC(ftrace_caller)
#endif

trace:
ldr r1, [fp, #-4] @ lr of instrumented routine
mov r0, lr
sub r0, r0, #MCOUNT_INSN_SIZE
mov lr, pc
mov pc, r2
ldr lr, [fp, #-4] @ restore lr
ldmia sp!, {r0-r3, pc}
ENDPROC(mcount)
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
ENTRY(ftrace_graph_caller)
__ftrace_graph_caller
ENDPROC(ftrace_graph_caller)
#endif

#endif /* CONFIG_DYNAMIC_FTRACE */
.purgem mcount_enter
.purgem mcount_get_lr
.purgem mcount_exit

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl return_to_handler
return_to_handler:
stmdb sp!, {r0-r3}
mov r0, fp @ frame pointer
bl ftrace_return_to_handler
mov lr, r0 @ r0 has real ret addr
ldmia sp!, {r0-r3}
mov pc, lr
#endif

ENTRY(ftrace_stub)
.Lftrace_stub:
Expand Down
Loading

0 comments on commit 83cf1ee

Please sign in to comment.