Hi Ralf, This one is also MIPS relative, also need your feedback ;) Thanks & Regards, Wu Zhangjin On Mon, 2009-10-26 at 23:13 +0800, Wu Zhangjin wrote: > 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@xxxxxxxxx> > --- > arch/mips/include/asm/irq.h | 29 ++--------------------------- > arch/mips/kernel/irq.c | 34 ++++++++++++++++++++++++++++++++++ > arch/mips/kernel/smp.c | 3 ++- > arch/mips/kernel/smtc.c | 21 ++++++++++++++------- > arch/mips/kernel/vmlinux.lds.S | 1 + > arch/mips/sgi-ip22/ip22-int.c | 3 ++- > arch/mips/sgi-ip22/ip22-time.c | 3 ++- > 7 files changed, 57 insertions(+), 37 deletions(-) > > diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h > index 09b08d0..6cdd8c2 100644 > --- a/arch/mips/include/asm/irq.h > +++ b/arch/mips/include/asm/irq.h > @@ -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 unsigned int 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 unsigned int do_IRQ_no_affinity(unsigned int irq); > > #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ > > diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c > index 7b845ba..c10ea8f 100644 > --- a/arch/mips/kernel/irq.c > +++ b/arch/mips/kernel/irq.c > @@ -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,36 @@ 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). > + */ > +unsigned int __irq_entry do_IRQ(unsigned int irq) > +{ > + irq_enter(); > + __DO_IRQ_SMTC_HOOK(irq); > + generic_handle_irq(irq); > + irq_exit(); > + > + return 1; > +} > + > +#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. > + */ > + > +unsigned int __irq_entry do_IRQ_no_affinity(unsigned int irq) > +{ > + irq_enter(); > + __NO_AFFINITY_IRQ_SMTC_HOOK(irq); > + generic_handle_irq(irq); > + irq_exit(); > + > + return 1; > +} > + > +#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ > diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c > index e72e684..6cdca19 100644 > --- a/arch/mips/kernel/smp.c > +++ b/arch/mips/kernel/smp.c > @@ -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(); > diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c > index 24630fd..75034a8 100644 > --- a/arch/mips/kernel/smtc.c > +++ b/arch/mips/kernel/smtc.c > @@ -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: > diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S > index 162b299..f25df73 100644 > --- a/arch/mips/kernel/vmlinux.lds.S > +++ b/arch/mips/kernel/vmlinux.lds.S > @@ -46,6 +46,7 @@ SECTIONS > SCHED_TEXT > LOCK_TEXT > KPROBES_TEXT > + IRQENTRY_TEXT > *(.text.*) > *(.fixup) > *(.gnu.warning) > diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c > index 0ecd5fe..383f11d 100644 > --- a/arch/mips/sgi-ip22/ip22-int.c > +++ b/arch/mips/sgi-ip22/ip22-int.c > @@ -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; > > diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c > index c8f7d23..603fc91 100644 > --- a/arch/mips/sgi-ip22/ip22-time.c > +++ b/arch/mips/sgi-ip22/ip22-time.c > @@ -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;