Blackfin: allow high priority domains to preempt schedule_tail()
authorPhilippe Gerum <rpm@xenomai.org>
Mon, 22 Jun 2009 16:23:32 +0000 (18:23 +0200)
committerMike Frysinger <vapier@gentoo.org>
Thu, 17 Sep 2009 01:28:33 +0000 (21:28 -0400)
ret_from_fork is always entered with hw interrupts off, which prevents
real-time domains to preempt the Linux kernel during part of the
initial context switch to the new task, which could in turn raise the
worst-case latency figures.

To avoid this, stall the root domain stage in the interrupt pipeline
to keep the scheduling tail code free from Linux-handled IRQs, then
enable hardware interrupts again.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
arch/blackfin/kernel/entry.S

index a9cfba9..3f8769b 100644 (file)
 
 ENTRY(_ret_from_fork)
 #ifdef CONFIG_IPIPE
-       [--sp] = reti;          /* IRQs on. */
-       SP += 4;
+       /*
+        * Hw IRQs are off on entry, and we don't want the scheduling tail
+        * code to starve high priority domains from interrupts while it
+        * runs. Therefore we first stall the root stage to have the
+        * virtual interrupt state reflect IMASK.
+        */
+       p0.l = ___ipipe_root_status;
+       p0.h = ___ipipe_root_status;
+       r4 = [p0];
+       bitset(r4, 0);
+       [p0] = r4;
+       /*
+        * Then we may enable hw IRQs, allowing preemption from high
+        * priority domains. schedule_tail() will do local_irq_enable()
+        * since Blackfin does not define __ARCH_WANT_UNLOCKED_CTXSW, so
+        * there is no need to unstall the root domain by ourselves
+        * afterwards.
+        */
+       p0.l = _bfin_irq_flags;
+       p0.h = _bfin_irq_flags;
+       r4 = [p0];
+       sti r4;
 #endif /* CONFIG_IPIPE */
        SP += -12;
        call _schedule_tail;