1. Use CONFIG_OPROFILE to get rid of overhead for null_perf_irq() call.
2. Call perf_irq from timer_interrupt instead of ll_timer_interrupt.
Most (non-SMP) boards will use timer_interrupt (instead of
ll_timer_interrupt), so it would be better to move calling of
perf_irq() to timer_interrupt().
3. Use jiffies instead of local timer_tick_count.
I can not test it by myself for now while I do not have any
MIPS32/MIPS64 board.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 7050b4f..7b5c5b9 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -414,6 +414,18 @@ void local_timer_interrupt(int irq, void
update_process_times(user_mode(regs));
}
+#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
+int null_perf_irq(struct pt_regs *regs)
+{
+ return 0;
+}
+
+int (*perf_irq)(struct pt_regs *regs) = null_perf_irq;
+
+EXPORT_SYMBOL(null_perf_irq);
+EXPORT_SYMBOL(perf_irq);
+#endif
+
/*
* High-level timer interrupt service routines. This function
* is set as irqaction->handler and is invoked through do_IRQ.
@@ -422,6 +434,22 @@ irqreturn_t timer_interrupt(int irq, voi
{
unsigned long j;
unsigned int count;
+#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
+ int r2 = cpu_has_mips_r2;
+
+ /*
+ * Suckage alert:
+ * Before R2 of the architecture there was no way to see if a
+ * performance counter interrupt was pending, so we have to run the
+ * performance counter interrupt handler anyway.
+ */
+ if (!r2 || (read_c0_cause() & (1 << 26)))
+ if (perf_irq(regs))
+ return IRQ_HANDLED;
+
+ if (r2 && !(read_c0_cause() & (1 << 30)))
+ return IRQ_HANDLED;
+#endif
count = mips_hpt_read();
mips_timer_ack();
@@ -507,38 +535,14 @@ irqreturn_t timer_interrupt(int irq, voi
return IRQ_HANDLED;
}
-int null_perf_irq(struct pt_regs *regs)
-{
- return 0;
-}
-
-int (*perf_irq)(struct pt_regs *regs) = null_perf_irq;
-
-EXPORT_SYMBOL(null_perf_irq);
-EXPORT_SYMBOL(perf_irq);
-
asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)
{
- int r2 = cpu_has_mips_r2;
-
irq_enter();
kstat_this_cpu.irqs[irq]++;
- /*
- * Suckage alert:
- * Before R2 of the architecture there was no way to see if a
- * performance counter interrupt was pending, so we have to run the
- * performance counter interrupt handler anyway.
- */
- if (!r2 || (read_c0_cause() & (1 << 26)))
- if (perf_irq(regs))
- goto out;
-
/* we keep interrupt disabled all the time */
- if (!r2 || (read_c0_cause() & (1 << 30)))
- timer_interrupt(irq, NULL, regs);
+ timer_interrupt(irq, NULL, regs);
-out:
irq_exit();
}
diff --git a/arch/mips/mips-boards/generic/time.c
b/arch/mips/mips-boards/generic/time.c
index 93f3bf2..f9471de 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -58,12 +58,11 @@ static char display_string[] = "
static unsigned int display_count = 0;
#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
-static unsigned int timer_tick_count=0;
static int mips_cpu_timer_irq;
static inline void scroll_display_message(void)
{
- if ((timer_tick_count++ % HZ) == 0) {
+ if ((jiffies % HZ) == 0) {
mips_display_message(&display_string[display_count++]);
if (display_count == MAX_DISPLAY_COUNT)
display_count = 0;
@@ -75,13 +74,8 @@ static void mips_timer_dispatch (struct
do_IRQ (mips_cpu_timer_irq, regs);
}
-extern int null_perf_irq(struct pt_regs *regs);
-
-extern int (*perf_irq)(struct pt_regs *regs);
-
irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- int r2 = cpu_has_mips_r2;
int cpu = smp_processor_id();
if (cpu == 0) {
@@ -90,13 +84,7 @@ irqreturn_t mips_timer_interrupt(int irq
* accounting resets count/compare registers to trigger next
* timer int.
*/
- if (!r2 || (read_c0_cause() & (1 << 26)))
- if (perf_irq(regs))
- goto out;
-
- /* we keep interrupt disabled all the time */
- if (!r2 || (read_c0_cause() & (1 << 30)))
- timer_interrupt(irq, NULL, regs);
+ timer_interrupt(irq, NULL, regs);
scroll_display_message();
} else {
@@ -114,7 +102,6 @@ irqreturn_t mips_timer_interrupt(int irq
local_timer_interrupt (irq, dev_id, regs);
}
-out:
return IRQ_HANDLED;
}
|