MIPS: Tracing: Add IRQENTRY_EXIT section for MIPS

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>
This commit is contained in:
Wu Zhangjin 2009-11-20 20:34:33 +08:00 committed by Ralf Baechle
parent 538f19526e
commit 8f99a16265
7 changed files with 53 additions and 37 deletions

View 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 */

View 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 */

View 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();

View 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:

View File

@ -46,6 +46,7 @@ SECTIONS
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
IRQENTRY_TEXT
*(.text.*)
*(.fixup)
*(.gnu.warning)

View 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;

View 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;