diff options
author | Wu Zhangjin <wuzhangjin@gmail.com> | 2009-11-20 07:34:33 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-12-16 20:57:24 -0500 |
commit | 8f99a162653531ef25a3dd0f92bfb6332cd2b295 (patch) | |
tree | 7dbb95ed810a1fe91c243e05b0d858a7846ec22c /arch/mips | |
parent | 538f19526e40ce7a5a296fad6a3121409c890adc (diff) |
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>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/include/asm/irq.h | 29 | ||||
-rw-r--r-- | arch/mips/kernel/irq.c | 30 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 3 | ||||
-rw-r--r-- | arch/mips/kernel/smtc.c | 21 | ||||
-rw-r--r-- | arch/mips/kernel/vmlinux.lds.S | 1 | ||||
-rw-r--r-- | arch/mips/sgi-ip22/ip22-int.c | 3 | ||||
-rw-r--r-- | arch/mips/sgi-ip22/ip22-time.c | 3 |
7 files changed, 53 insertions, 37 deletions
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 09b08d05ff72..06960364c96b 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h | |||
@@ -113,36 +113,11 @@ do { \ | |||
113 | 113 | ||
114 | #endif | 114 | #endif |
115 | 115 | ||
116 | /* | 116 | extern void do_IRQ(unsigned int irq); |
117 | * do_IRQ handles all normal device IRQ's (the special | ||
118 | * SMP cross-CPU interrupts have their own specific | ||
119 | * handlers). | ||
120 | * | ||
121 | * Ideally there should be away to get this into kernel/irq/handle.c to | ||
122 | * avoid the overhead of a call for just a tiny function ... | ||
123 | */ | ||
124 | #define do_IRQ(irq) \ | ||
125 | do { \ | ||
126 | irq_enter(); \ | ||
127 | __DO_IRQ_SMTC_HOOK(irq); \ | ||
128 | generic_handle_irq(irq); \ | ||
129 | irq_exit(); \ | ||
130 | } while (0) | ||
131 | 117 | ||
132 | #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF | 118 | #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF |
133 | /* | ||
134 | * To avoid inefficient and in some cases pathological re-checking of | ||
135 | * IRQ affinity, we have this variant that skips the affinity check. | ||
136 | */ | ||
137 | |||
138 | 119 | ||
139 | #define do_IRQ_no_affinity(irq) \ | 120 | extern void do_IRQ_no_affinity(unsigned int irq); |
140 | do { \ | ||
141 | irq_enter(); \ | ||
142 | __NO_AFFINITY_IRQ_SMTC_HOOK(irq); \ | ||
143 | generic_handle_irq(irq); \ | ||
144 | irq_exit(); \ | ||
145 | } while (0) | ||
146 | 121 | ||
147 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ | 122 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ |
148 | 123 | ||
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 8b0b4181219f..981f86c26168 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/kallsyms.h> | 23 | #include <linux/kallsyms.h> |
24 | #include <linux/kgdb.h> | 24 | #include <linux/kgdb.h> |
25 | #include <linux/ftrace.h> | ||
25 | 26 | ||
26 | #include <asm/atomic.h> | 27 | #include <asm/atomic.h> |
27 | #include <asm/system.h> | 28 | #include <asm/system.h> |
@@ -150,3 +151,32 @@ void __init init_IRQ(void) | |||
150 | kgdb_early_setup = 1; | 151 | kgdb_early_setup = 1; |
151 | #endif | 152 | #endif |
152 | } | 153 | } |
154 | |||
155 | /* | ||
156 | * do_IRQ handles all normal device IRQ's (the special | ||
157 | * SMP cross-CPU interrupts have their own specific | ||
158 | * handlers). | ||
159 | */ | ||
160 | void __irq_entry do_IRQ(unsigned int irq) | ||
161 | { | ||
162 | irq_enter(); | ||
163 | __DO_IRQ_SMTC_HOOK(irq); | ||
164 | generic_handle_irq(irq); | ||
165 | irq_exit(); | ||
166 | } | ||
167 | |||
168 | #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF | ||
169 | /* | ||
170 | * To avoid inefficient and in some cases pathological re-checking of | ||
171 | * IRQ affinity, we have this variant that skips the affinity check. | ||
172 | */ | ||
173 | |||
174 | void __irq_entry do_IRQ_no_affinity(unsigned int irq) | ||
175 | { | ||
176 | irq_enter(); | ||
177 | __NO_AFFINITY_IRQ_SMTC_HOOK(irq); | ||
178 | generic_handle_irq(irq); | ||
179 | irq_exit(); | ||
180 | } | ||
181 | |||
182 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ | ||
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index e72e6844d134..6cdca1956b77 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/cpumask.h> | 32 | #include <linux/cpumask.h> |
33 | #include <linux/cpu.h> | 33 | #include <linux/cpu.h> |
34 | #include <linux/err.h> | 34 | #include <linux/err.h> |
35 | #include <linux/ftrace.h> | ||
35 | 36 | ||
36 | #include <asm/atomic.h> | 37 | #include <asm/atomic.h> |
37 | #include <asm/cpu.h> | 38 | #include <asm/cpu.h> |
@@ -130,7 +131,7 @@ asmlinkage __cpuinit void start_secondary(void) | |||
130 | /* | 131 | /* |
131 | * Call into both interrupt handlers, as we share the IPI for them | 132 | * Call into both interrupt handlers, as we share the IPI for them |
132 | */ | 133 | */ |
133 | void smp_call_function_interrupt(void) | 134 | void __irq_entry smp_call_function_interrupt(void) |
134 | { | 135 | { |
135 | irq_enter(); | 136 | irq_enter(); |
136 | generic_smp_call_function_single_interrupt(); | 137 | generic_smp_call_function_single_interrupt(); |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index a38e3ee95515..23499b5bd9c3 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/kernel_stat.h> | 26 | #include <linux/kernel_stat.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/ftrace.h> | ||
28 | 29 | ||
29 | #include <asm/cpu.h> | 30 | #include <asm/cpu.h> |
30 | #include <asm/processor.h> | 31 | #include <asm/processor.h> |
@@ -939,23 +940,29 @@ static void ipi_call_interrupt(void) | |||
939 | 940 | ||
940 | DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); | 941 | DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); |
941 | 942 | ||
942 | void ipi_decode(struct smtc_ipi *pipi) | 943 | static void __irq_entry smtc_clock_tick_interrupt(void) |
943 | { | 944 | { |
944 | unsigned int cpu = smp_processor_id(); | 945 | unsigned int cpu = smp_processor_id(); |
945 | struct clock_event_device *cd; | 946 | struct clock_event_device *cd; |
947 | int irq = MIPS_CPU_IRQ_BASE + 1; | ||
948 | |||
949 | irq_enter(); | ||
950 | kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); | ||
951 | cd = &per_cpu(mips_clockevent_device, cpu); | ||
952 | cd->event_handler(cd); | ||
953 | irq_exit(); | ||
954 | } | ||
955 | |||
956 | void ipi_decode(struct smtc_ipi *pipi) | ||
957 | { | ||
946 | void *arg_copy = pipi->arg; | 958 | void *arg_copy = pipi->arg; |
947 | int type_copy = pipi->type; | 959 | int type_copy = pipi->type; |
948 | int irq = MIPS_CPU_IRQ_BASE + 1; | ||
949 | 960 | ||
950 | smtc_ipi_nq(&freeIPIq, pipi); | 961 | smtc_ipi_nq(&freeIPIq, pipi); |
951 | 962 | ||
952 | switch (type_copy) { | 963 | switch (type_copy) { |
953 | case SMTC_CLOCK_TICK: | 964 | case SMTC_CLOCK_TICK: |
954 | irq_enter(); | 965 | smtc_clock_tick_interrupt(); |
955 | kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); | ||
956 | cd = &per_cpu(mips_clockevent_device, cpu); | ||
957 | cd->event_handler(cd); | ||
958 | irq_exit(); | ||
959 | break; | 966 | break; |
960 | 967 | ||
961 | case LINUX_SMP_IPI: | 968 | case LINUX_SMP_IPI: |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 162b29954baa..f25df73db923 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -46,6 +46,7 @@ SECTIONS | |||
46 | SCHED_TEXT | 46 | SCHED_TEXT |
47 | LOCK_TEXT | 47 | LOCK_TEXT |
48 | KPROBES_TEXT | 48 | KPROBES_TEXT |
49 | IRQENTRY_TEXT | ||
49 | *(.text.*) | 50 | *(.text.*) |
50 | *(.fixup) | 51 | *(.fixup) |
51 | *(.gnu.warning) | 52 | *(.gnu.warning) |
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index 0ecd5fe9486e..383f11d7f442 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/kernel_stat.h> | 14 | #include <linux/kernel_stat.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/ftrace.h> | ||
16 | 17 | ||
17 | #include <asm/irq_cpu.h> | 18 | #include <asm/irq_cpu.h> |
18 | #include <asm/sgi/hpc3.h> | 19 | #include <asm/sgi/hpc3.h> |
@@ -150,7 +151,7 @@ static void indy_local1_irqdispatch(void) | |||
150 | 151 | ||
151 | extern void ip22_be_interrupt(int irq); | 152 | extern void ip22_be_interrupt(int irq); |
152 | 153 | ||
153 | static void indy_buserror_irq(void) | 154 | static void __irq_entry indy_buserror_irq(void) |
154 | { | 155 | { |
155 | int irq = SGI_BUSERR_IRQ; | 156 | int irq = SGI_BUSERR_IRQ; |
156 | 157 | ||
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c index c8f7d2328b24..603fc91c1030 100644 --- a/arch/mips/sgi-ip22/ip22-time.c +++ b/arch/mips/sgi-ip22/ip22-time.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/kernel_stat.h> | 17 | #include <linux/kernel_stat.h> |
18 | #include <linux/time.h> | 18 | #include <linux/time.h> |
19 | #include <linux/ftrace.h> | ||
19 | 20 | ||
20 | #include <asm/cpu.h> | 21 | #include <asm/cpu.h> |
21 | #include <asm/mipsregs.h> | 22 | #include <asm/mipsregs.h> |
@@ -115,7 +116,7 @@ __init void plat_time_init(void) | |||
115 | } | 116 | } |
116 | 117 | ||
117 | /* Generic SGI handler for (spurious) 8254 interrupts */ | 118 | /* Generic SGI handler for (spurious) 8254 interrupts */ |
118 | void indy_8254timer_irq(void) | 119 | void __irq_entry indy_8254timer_irq(void) |
119 | { | 120 | { |
120 | int irq = SGI_8254_0_IRQ; | 121 | int irq = SGI_8254_0_IRQ; |
121 | ULONG cnt; | 122 | ULONG cnt; |