SMP issues on ARM11 MPCore
mkl lin
mkl0301 at hotmail.com
Tue Jan 5 11:02:22 EST 2010
> These two sounds like a problem with interrupts - userspace console IO
> is interrupt driven, whereas kernel console IO is not.
Thanks for Russell's
advice, after some tracing, I found that my IER (Interrupt Enable
Register) of the serial port is 0 under case 1!!
Case 2 is
actually the same with case 1. Case 1 would come first, if I don't keep
input things and let it finish its slow printing, it would then become
case 2.
UART_BUG_THRE are detected and enabled on my platform, causing serial8250_backup_timeout to be used.
There
are many places that do ( get IER, clear IER, restore IER ), like
serial8250_console_write called by printk, and
serial8250_backup_timeout. serial8250_backup_timeout is not protected
by spinlock, causing the race condition, and result in wrong IER value.
Following patch fix this issue. Case 3 and Case 4 are still often seen, but not case 1 and case 2.
Best Regards,
Mac Lin
diff --git a/kernels/linux-2.6.31.1-X/drivers/serial/8250.c b/kernels/linux-2.6.31.1-X/drivers/serial/8250.c
index 288a0e4..55602c3 100644
--- a/kernels/linux-2.6.31.1-cavm1/drivers/serial/8250.c
+++ b/kernels/linux-2.6.31.1-cavm1/drivers/serial/8250.c
@@ -1752,6 +1758,8 @@ static void serial8250_backup_timeout(unsigned long data)
unsigned int iir, ier = 0, lsr;
unsigned long flags;
+
+ spin_lock_irqsave(&up->port.lock, flags);
/*
* Must disable interrupts or else we risk racing with the interrupt
* based handler.
@@ -1769,10 +1777,8 @@ static void serial8250_backup_timeout(unsigned long data)
* the "Diva" UART used on the management processor on many HP
* ia64 and parisc boxes.
*/
- spin_lock_irqsave(&up->port.lock, flags);
lsr = serial_in(up, UART_LSR);
up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
- spin_unlock_irqrestore(&up->port.lock, flags);
if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
(!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
(lsr & UART_LSR_THRE)) {
@@ -1780,12 +1786,14 @@ static void serial8250_backup_timeout(unsigned long data)
iir |= UART_IIR_THRI;
}
- if (!(iir & UART_IIR_NO_INT))
- serial8250_handle_port(up);
-
if (is_real_interrupt(up->port.irq))
serial_out(up, UART_IER, ier);
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+ if (!(iir & UART_IIR_NO_INT))
+ serial8250_handle_port(up);
+
/* Standard timer interval plus 0.2s to keep the port running */
mod_timer(&up->timer,
jiffies + poll_timeout(up->port.timeout) + HZ / 5);
_________________________________________________________________
Windows Live Hotmail: Your friends can get your Facebook updates, right from Hotmail®.
http://www.microsoft.com/middleeast/windows/windowslive/see-it-in-action/social-network-basics.aspx?ocid=PID23461::T:WLMTAGL:ON:WL:en-xm:SI_SB_4:092009
More information about the linux-arm-kernel
mailing list