Re: [PATCH] FRV: Use the generic IRQ stuff

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Okay... I've got some timings for FRV using my non-genirq code and using the
generic IRQ code.

Adding the attached patch (or similar) into the kernel, I see the following
timings:

				do_IRQ->timer_int	timer_int->do_IRQ
			Cache	Cycles	Time		Cycles	Time
	===============	=======	=======================	=====================
	non-genirq	Cold	380	1.1uS		216	600nS
			Warm	114	320nS		96	270nS
	genirq		Cold	503	1.4uS		409	1.1uS
			Warm	87	240nS		99	270nS

The TIMERL counter increments at core clock speed (360MHz), so each cycle is
approx 2.8nS.  Each cycle executes on instruction or one pair of packed
instructions under ideal circumstances.  Misjudged branches cost 4 clock
cycles.

So the genirq patch bites you on a cold cache, probably due to all the little
bits of unpredictable icache it's got to collect (chip ops and suchlike
dangling off function pointers), but wins a bit on the warm cache front.

The genirq timings above are with __do_IRQ() removed from the kernel.

I used gdb to collect the timings.  The times are initially very high, but
quickly settle to constant lower values.

David
---
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 5ac041c..8bcb980 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -134,6 +134,10 @@ static struct irq_chip frv_cpu_pic = {
 	.end		= frv_cpupic_end,
 };
 
+unsigned long irq_entered_at;
+unsigned long irq_handler_entered_at;
+unsigned long irq_exited_at;
+
 /*
  * handles all normal device IRQ's
  * - registers are referred to by the __frame variable (GR28)
@@ -142,9 +146,15 @@ static struct irq_chip frv_cpu_pic = {
  */
 asmlinkage void do_IRQ(void)
 {
+	asm volatile ("bar" ::: "memory");
+	asm volatile ("movsg timerl,%0" : "=r"(irq_entered_at) :: "memory");
 	irq_enter();
 	generic_handle_irq(__get_IRL(), __frame);
 	irq_exit();
+	asm volatile ("bar" ::: "memory");
+	asm volatile ("movsg timerl,%0" : "=r"(irq_exited_at) :: "memory");
+	asm volatile ("bar" ::: "memory");
+	asm volatile ("break" ::: "memory");
 }
 
 /*
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 3d0284b..772b409 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -52,12 +52,18 @@ static inline int set_rtc_mmss(unsigned 
 	return -1;
 }
 
+extern unsigned long irq_handler_entered_at;
+
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
 static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
 {
+	asm volatile ("movsg timerl,%0" : "=r"(irq_handler_entered_at) :: "memory");
+	return IRQ_HANDLED;
+
+#if 0
 	/* last time the cmos clock got updated */
 	static long last_rtc_update = 0;
 
@@ -98,6 +104,7 @@ #endif /* CONFIG_HEARTBEAT */
 
 	write_sequnlock(&xtime_lock);
 	return IRQ_HANDLED;
+#endif
 }
 
 void time_divisor_init(void)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux