MIPS: Tracing: Add IRQENTRY_EXIT section for MIPS
authorWu Zhangjin <wuzhangjin@gmail.com>
Fri, 20 Nov 2009 12:34:33 +0000 (20:34 +0800)
committerRalf Baechle <ralf@linux-mips.org>
Thu, 17 Dec 2009 01:57:24 +0000 (01:57 +0000)
This patch add a new section for MIPS to record the block of the hardirq
handling for function graph tracer(print_graph_irq) via adding the
__irq_entry annotation to the the entrypoints of the hardirqs(the block
with irq_enter()...irq_exit()).

Thanks goes to Steven & Frederic Weisbecker for their feedbacks.

Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Nicholas Mc Guire <der.herr@hofr.at>
Cc: zhangfx@lemote.com
Cc: Wu Zhangjin <wuzhangjin@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mips@linux-mips.org
Reviewed-by: Frederic Weisbecker <fweisbec@gmail.com>
Patchwork: http://patchwork.linux-mips.org/patch/676/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/irq.h
arch/mips/kernel/irq.c
arch/mips/kernel/smp.c
arch/mips/kernel/smtc.c
arch/mips/kernel/vmlinux.lds.S
arch/mips/sgi-ip22/ip22-int.c
arch/mips/sgi-ip22/ip22-time.c

index 09b08d0..0696036 100644 (file)
@@ -113,36 +113,11 @@ do {                                                                      \
 
 #endif
 
-/*
- * do_IRQ handles all normal device IRQ's (the special
- * SMP cross-CPU interrupts have their own specific
- * handlers).
- *
- * Ideally there should be away to get this into kernel/irq/handle.c to
- * avoid the overhead of a call for just a tiny function ...
- */
-#define do_IRQ(irq)                                                    \
-do {                                                                   \
-       irq_enter();                                                    \
-       __DO_IRQ_SMTC_HOOK(irq);                                        \
-       generic_handle_irq(irq);                                        \
-       irq_exit();                                                     \
-} while (0)
+extern void do_IRQ(unsigned int irq);
 
 #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
-/*
- * To avoid inefficient and in some cases pathological re-checking of
- * IRQ affinity, we have this variant that skips the affinity check.
- */
-
 
-#define do_IRQ_no_affinity(irq)                                                \
-do {                                                                   \
-       irq_enter();                                                    \
-       __NO_AFFINITY_IRQ_SMTC_HOOK(irq);                               \
-       generic_handle_irq(irq);                                        \
-       irq_exit();                                                     \
-} while (0)
+extern void do_IRQ_no_affinity(unsigned int irq);
 
 #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
 
index 8b0b418..981f86c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/seq_file.h>
 #include <linux/kallsyms.h>
 #include <linux/kgdb.h>
+#include <linux/ftrace.h>
 
 #include <asm/atomic.h>
 #include <asm/system.h>
@@ -150,3 +151,32 @@ void __init init_IRQ(void)
                kgdb_early_setup = 1;
 #endif
 }
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special
+ * SMP cross-CPU interrupts have their own specific
+ * handlers).
+ */
+void __irq_entry do_IRQ(unsigned int irq)
+{
+       irq_enter();
+       __DO_IRQ_SMTC_HOOK(irq);
+       generic_handle_irq(irq);
+       irq_exit();
+}
+
+#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+/*
+ * To avoid inefficient and in some cases pathological re-checking of
+ * IRQ affinity, we have this variant that skips the affinity check.
+ */
+
+void __irq_entry do_IRQ_no_affinity(unsigned int irq)
+{
+       irq_enter();
+       __NO_AFFINITY_IRQ_SMTC_HOOK(irq);
+       generic_handle_irq(irq);
+       irq_exit();
+}
+
+#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
index e72e684..6cdca19 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/cpumask.h>
 #include <linux/cpu.h>
 #include <linux/err.h>
+#include <linux/ftrace.h>
 
 #include <asm/atomic.h>
 #include <asm/cpu.h>
@@ -130,7 +131,7 @@ asmlinkage __cpuinit void start_secondary(void)
 /*
  * Call into both interrupt handlers, as we share the IPI for them
  */
-void smp_call_function_interrupt(void)
+void __irq_entry smp_call_function_interrupt(void)
 {
        irq_enter();
        generic_smp_call_function_single_interrupt();
index a38e3ee..23499b5 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
+#include <linux/ftrace.h>
 
 #include <asm/cpu.h>
 #include <asm/processor.h>
@@ -939,23 +940,29 @@ static void ipi_call_interrupt(void)
 
 DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device);
 
-void ipi_decode(struct smtc_ipi *pipi)
+static void __irq_entry smtc_clock_tick_interrupt(void)
 {
        unsigned int cpu = smp_processor_id();
        struct clock_event_device *cd;
+       int irq = MIPS_CPU_IRQ_BASE + 1;
+
+       irq_enter();
+       kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
+       cd = &per_cpu(mips_clockevent_device, cpu);
+       cd->event_handler(cd);
+       irq_exit();
+}
+
+void ipi_decode(struct smtc_ipi *pipi)
+{
        void *arg_copy = pipi->arg;
        int type_copy = pipi->type;
-       int irq = MIPS_CPU_IRQ_BASE + 1;
 
        smtc_ipi_nq(&freeIPIq, pipi);
 
        switch (type_copy) {
        case SMTC_CLOCK_TICK:
-               irq_enter();
-               kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
-               cd = &per_cpu(mips_clockevent_device, cpu);
-               cd->event_handler(cd);
-               irq_exit();
+               smtc_clock_tick_interrupt();
                break;
 
        case LINUX_SMP_IPI:
index 162b299..f25df73 100644 (file)
@@ -46,6 +46,7 @@ SECTIONS
                SCHED_TEXT
                LOCK_TEXT
                KPROBES_TEXT
+               IRQENTRY_TEXT
                *(.text.*)
                *(.fixup)
                *(.gnu.warning)
index 0ecd5fe..383f11d 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/ftrace.h>
 
 #include <asm/irq_cpu.h>
 #include <asm/sgi/hpc3.h>
@@ -150,7 +151,7 @@ static void indy_local1_irqdispatch(void)
 
 extern void ip22_be_interrupt(int irq);
 
-static void indy_buserror_irq(void)
+static void __irq_entry indy_buserror_irq(void)
 {
        int irq = SGI_BUSERR_IRQ;
 
index c8f7d23..603fc91 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/time.h>
+#include <linux/ftrace.h>
 
 #include <asm/cpu.h>
 #include <asm/mipsregs.h>
@@ -115,7 +116,7 @@ __init void plat_time_init(void)
 }
 
 /* Generic SGI handler for (spurious) 8254 interrupts */
-void indy_8254timer_irq(void)
+void __irq_entry indy_8254timer_irq(void)
 {
        int irq = SGI_8254_0_IRQ;
        ULONG cnt;