[syslinux:lwip] pxe: always start the idle thread, in case we need it

syslinux-bot for H. Peter Anvin hpa at zytor.com
Tue May 29 19:36:03 PDT 2012


Commit-ID:  7699e996c613e51049e0bad6ade32215ac263289
Gitweb:     http://www.syslinux.org/commit/7699e996c613e51049e0bad6ade32215ac263289
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Tue, 29 May 2012 19:33:20 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Tue, 29 May 2012 19:33:20 -0700

pxe: always start the idle thread, in case we need it

Always start the idle thread, but leave it blocked unless we have an
indication that interrupts are not working.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>

---
 core/fs/pxe/isr.c         |   36 ++++++++++++++++++++++++++++--------
 core/pxeisr.inc           |    7 ++++---
 core/thread/idle_thread.c |    7 +++++++
 3 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index e2bf2f6..69cfe9f 100644
--- a/core/fs/pxe/isr.c
+++ b/core/fs/pxe/isr.c
@@ -13,8 +13,9 @@
 #include <sys/io.h>
 
 extern uint8_t pxe_irq_pending;
-extern volatile uint8_t pxe_irq_timeout;
+extern volatile uint8_t pxe_need_poll;
 static DECLARE_INIT_SEMAPHORE(pxe_receive_thread_sem, 0);
+static DECLARE_INIT_SEMAPHORE(pxe_poll_thread_sem, 0);
 static struct thread *pxe_thread, *poll_thread;
 
 /*
@@ -26,6 +27,7 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old)
     unsigned int vec;
     uint8_t mask, mymask;
     uint32_t now;
+    bool ok;
 
     if (irq < 8)
 	vec = irq + 0x08;
@@ -36,6 +38,11 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old)
 
     cli();
 
+    if (pxe_need_poll) {
+	sti();
+	return false;
+    }
+
     entry = (far_ptr_t *)(vec << 2);
     *old = *entry;
     entry->ptr = (uint32_t)isr;
@@ -60,16 +67,16 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old)
     now = jiffies();
 
     /* Some time to watch for stuck interrupts */
-    while (jiffies() - now < 4 && !pxe_irq_timeout)
+    while (jiffies() - now < 4 && (ok = !pxe_need_poll))
 	hlt();
 
-    if (pxe_irq_timeout)
+    if (!ok)
 	*entry = *old;		/* Restore the old vector */
 
     printf("UNDI: IRQ %d(0x%02x): %04x:%04x -> %04x:%04x\n", irq, vec,
 	   old->seg, old->offs, entry->seg, entry->offs);
 
-    return !pxe_irq_timeout;
+    return ok;
 }
 
 static bool uninstall_irq_vector(uint8_t irq, void (*isr), far_ptr_t *old)
@@ -108,6 +115,12 @@ static void pxe_poll_wakeups(void)
     static jiffies_t last_jiffies = 0;
     jiffies_t now = jiffies();
 
+    if (pxe_need_poll == 1) {
+	/* If we need polling now, activate polling */
+	pxe_need_poll = 3;
+	sem_up(&pxe_poll_thread_sem);
+    }
+
     if (now != last_jiffies) {
 	last_jiffies = now;
 	__thread_process_timeouts();
@@ -183,11 +196,15 @@ static void pxe_poll_thread(void *dummy)
 {
     (void)dummy;
 
+    /* Block indefinitely unless activated */
+    sem_down(&pxe_poll_thread_sem, 0);
+
     for (;;) {
 	cli();
 	if (pxe_receive_thread_sem.count < 0 && pxe_isr_poll())
 	    sem_up(&pxe_receive_thread_sem);
-	__schedule();
+	else
+	    __schedule();
 	sti();
 	cpu_relax();
     }
@@ -206,9 +223,10 @@ void pxe_init_isr(void)
      * avoid packet loss we need to move it into memory that we ourselves
      * manage, as soon as possible.
      */
+    core_pm_hook = __schedule;
+
     pxe_thread = start_thread("pxe receive", 16384, -20,
 			      pxe_receive_thread, NULL);
-    core_pm_hook = __schedule;
 }
 
 /*
@@ -230,9 +248,11 @@ void pxe_start_isr(void)
 	    irq = 0;		/* Install failed or stuck interrupt */
     }
     
+    poll_thread = start_thread("pxe poll", 4096, POLL_THREAD_PRIORITY,
+			       pxe_poll_thread, NULL);
+
     if (!irq ||	!(pxe_undi_iface.ServiceFlags & PXE_UNDI_IFACE_FLAG_IRQ))
-	poll_thread = start_thread("pxe poll", 4096, POLL_THREAD_PRIORITY,
-				   pxe_poll_thread, NULL);
+	pxe_need_poll |= 1;
 }
 
 int reset_pxe(void)
diff --git a/core/pxeisr.inc b/core/pxeisr.inc
index 6f9844e..5bcb924 100644
--- a/core/pxeisr.inc
+++ b/core/pxeisr.inc
@@ -95,7 +95,7 @@ pxe_irq_chain	equ $-4
 		in al,dx
 		or al,ch
 		out dx,al
-		mov byte [pxe_irq_timeout],1
+		or byte [pxe_need_poll],1
 		jmp .exit
 
 
@@ -162,7 +162,8 @@ pxeirq_count	resw 1
 pxe_irq_vector	resb 1			; PXE IRQ vector
 		global pxe_irq_pending
 pxe_irq_pending	resb 1			; IRQ pending flag
-		global pxe_irq_timeout
-pxe_irq_timeout	resb 1			; Stuck IRQs, disabled timeout
+		global pxe_need_poll
+pxe_need_poll	resb 1			; Bit 0 = need polling
+					; Bit 1 = polling active
 
 		section .text16
diff --git a/core/thread/idle_thread.c b/core/thread/idle_thread.c
index 4555333..8faa071 100644
--- a/core/thread/idle_thread.c
+++ b/core/thread/idle_thread.c
@@ -2,12 +2,19 @@
 #include <limits.h>
 #include <sys/cpu.h>
 
+static void default_idle_thread_hook(void)
+{
+}
+
+void (*idle_thread_hook)(void) = default_idle_thread_hook;
+
 static void idle_thread_func(void *dummy)
 {
     (void)dummy;
 
     for (;;) {
 	cli();
+	idle_thread_hook();
 	__schedule();
 	asm volatile("sti ; hlt" : : : "memory");
     }


More information about the Syslinux-commits mailing list