Kaynağa Gözat

Blackfin: allow high priority domains to preempt schedule_tail()

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>
Philippe Gerum 16 yıl önce
ebeveyn
işleme
6b8019c85e
1 değiştirilmiş dosya ile 22 ekleme ve 2 silme
  1. 22 2
      arch/blackfin/kernel/entry.S

+ 22 - 2
arch/blackfin/kernel/entry.S

@@ -43,8 +43,28 @@
 
 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;