Thread (35 messages) 35 messages, 4 authors, 2014-09-10

[PATCH v8 00/18] 8250-core based serial driver for OMAP + DMA

From: bigeasy@linutronix.de (Sebastian Andrzej Siewior)
Date: 2014-09-08 15:15:17
Also in: linux-omap, linux-serial, lkml
Subsystem: 8250/16?50 (and clone uarts) serial driver, the rest, tty layer and serial drivers · Maintainers: Greg Kroah-Hartman, Linus Torvalds, Jiri Slaby

* Frans Klaver | 2014-09-08 16:46:18 [+0200]:
- ncurses based applications (vi, less) don't play nice for me on the
 console with this series. less doesn't show me anything. vi doesn't
 return to console properly.
Can you give a test case 
- I seem seem to get stuck in a "serial8250: too much work for irq%d"
 loop somewhat reliably. We have a rather demanding application with
 typically somewhere between 600 and 1000 byte packets being sent at
 240Hz (roughly somewhere between 1.5 and 2 Mb/s). We run at baudrate
 3500k. I get into this "too much work" thing already when running at
 300 bytes per packet.
Do you get this message also at lower baud rates, say 115200?

What I am trying to understand is why you are spinning in the handler. 
_With_ DMA you should hardly get into the serial handler under normal 
conditions. Running at 3.5MB/sec should give one byte every 2.8us and
48 Bytes every ~137us. This looks like plenty of time to get  out of
the handler. My *guess* is that serial8250_handle_irq() has IIR often
set to timeout and you end up fetching byte after byte. 

This patch should protocol when and why you got into the handler.
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 7111b22de000..59852069e4a0 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1583,6 +1583,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 	status = serial_port_in(port, UART_LSR);
 
 	DEBUG_INTR("status = %x...", status);
+	trace_printk("l%d IIR %x LSR %x\n", port->line, iir, status);
 
 	if (status & (UART_LSR_DR | UART_LSR_BI)) {
 		if (up->dma)
@@ -1707,6 +1708,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 
 	spin_unlock(&i->lock);
 
+	trace_printk("%d e\n", irq);
 	DEBUG_INTR("end.\n");
 
 	return IRQ_RETVAL(handled);
I hope this is of some use to you. I'll do more testing later.
Which SoC do you use and do you have DMA enabled?
Thanks,
Frans
Sebastian
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help