From 4eca1f9032684ed50bef1c22a6672e16b18b772a Mon Sep 17 00:00:00 2001 From: Zwane Mwaikambo Date: Sat, 4 Sep 2004 02:18:35 -0700 Subject: [PATCH] [PATCH] out-of-line locks / arm Signed-off-by: Zwane Mwaikambo Signed-off-by: Linus Torvalds --- arch/arm/kernel/time.c | 17 ++++++++++++++++- arch/arm/kernel/vmlinux.lds.S | 1 + arch/arm/oprofile/op_model_xscale.c | 4 ++-- include/asm-arm/ptrace.h | 5 +++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 41bbacfc7bce2..86b2b897a4797 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -33,7 +33,7 @@ #include #include #include - +#include #include u64 jiffies_64 = INITIAL_JIFFIES; @@ -52,6 +52,21 @@ EXPORT_SYMBOL(rtc_lock); /* change this if you have some constant time drift */ #define USECS_PER_JIFFY (1000000/HZ) +#ifdef CONFIG_SMP +unsigned long profile_pc(struct pt_regs *regs) +{ + unsigned long fp, pc = instruction_pointer(regs); + + if (pc >= (unsigned long)&__lock_text_start && + pc <= (unsigned long)&__lock_text_end) { + fp = thread_saved_fp(current); + pc = pc_pointer(((unsigned long *)fp)[-1]); + } + + return pc; +} +EXPORT_SYMBOL(profile_pc); +#endif /* * hook for setting the RTC's idea of the current time. diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 355c8959d590f..1131500de2ad4 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -71,6 +71,7 @@ SECTIONS _text = .; /* Text and read-only data */ *(.text) SCHED_TEXT + LOCK_TEXT *(.fixup) *(.gnu.warning) *(.rodata) diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c index d77e18fa71bc8..447653df1c144 100644 --- a/arch/arm/oprofile/op_model_xscale.c +++ b/arch/arm/oprofile/op_model_xscale.c @@ -343,7 +343,7 @@ static void inline __xsc2_check_ctrs(void) static irqreturn_t xscale_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) { - unsigned long eip = instruction_pointer(regs); + unsigned long pc = profile_pc(regs); int i, is_kernel = !user_mode(regs); u32 pmnc; @@ -357,7 +357,7 @@ static irqreturn_t xscale_pmu_interrupt(int irq, void *arg, struct pt_regs *regs continue; write_counter(i, -(u32)results[i].reset_counter); - oprofile_add_sample(eip, is_kernel, i, smp_processor_id()); + oprofile_add_sample(pc, is_kernel, i, smp_processor_id()); results[i].ovf--; } diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h index 0b270a32c5880..f227d7d0a6a0f 100644 --- a/include/asm-arm/ptrace.h +++ b/include/asm-arm/ptrace.h @@ -130,7 +130,12 @@ static inline int valid_user_regs(struct pt_regs *regs) #define instruction_pointer(regs) \ (pc_pointer((regs)->ARM_pc)) + +#ifdef CONFIG_SMP +extern unsigned long profile_pc(struct pt_regs *regs); +#else #define profile_pc(regs) instruction_pointer(regs) +#endif #ifdef __KERNEL__ extern void show_regs(struct pt_regs *); -- 2.53.0