ARM: place C irq handlers in IRQ_ENTRY for ftrace
Rabin Vincent [Thu, 7 Oct 2010 15:21:58 +0000 (20:21 +0530)]
When FUNCTION_GRAPH_TRACER is enabled, place do_IRQ() and friends in the
IRQ_ENTRY section so that the irq-related features of the function graph
tracer work.

Signed-off-by: Rabin Vincent <rabin@rab.in>

arch/arm/include/asm/system.h
arch/arm/include/asm/traps.h
arch/arm/kernel/irq.c
arch/arm/kernel/smp.c
arch/arm/kernel/vmlinux.lds.S

index 1120f18..ec4327a 100644 (file)
 #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;
index 491960b..124475a 100644 (file)
@@ -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);
index 36ad3be..6d61633 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/list.h>
 #include <linux/kallsyms.h>
 #include <linux/proc_fs.h>
+#include <linux/ftrace.h>
 
 #include <asm/system.h>
 #include <asm/mach/irq.h>
@@ -105,7 +106,8 @@ unlock:
  * come via this function.  Instead, they should provide their
  * own 'handler'
  */
-asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+asmlinkage void __exception_irq_entry
+asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
 
index 8c19595..bbca898 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/cache.h>
 #include <linux/profile.h>
 #include <linux/errno.h>
+#include <linux/ftrace.h>
 #include <linux/mm.h>
 #include <linux/err.h>
 #include <linux/cpu.h>
@@ -457,7 +458,7 @@ static void ipi_timer(void)
 }
 
 #ifdef CONFIG_LOCAL_TIMERS
-asmlinkage void __exception do_local_timer(struct pt_regs *regs)
+asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
        int cpu = smp_processor_id();
@@ -544,7 +545,7 @@ static void ipi_cpu_stop(unsigned int cpu)
  *
  *  Bit 0 - Inter-processor function call
  */
-asmlinkage void __exception do_IPI(struct pt_regs *regs)
+asmlinkage void __exception_irq_entry do_IPI(struct pt_regs *regs)
 {
        unsigned int cpu = smp_processor_id();
        struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
index cead889..897c1a8 100644 (file)
@@ -101,6 +101,7 @@ SECTIONS
                        __exception_text_start = .;
                        *(.exception.text)
                        __exception_text_end = .;
+                       IRQENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
                        LOCK_TEXT