Re: RFC: Support DMA timeout interrupt for UART Rx

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2016-02-25 at 20:10 +0000, Greg KH wrote:
> On Thu, Feb 25, 2016 at 05:59:00PM +0000, Shevchenko, Andriy wrote:
> > 
> Email footers like this prevent many people, including myself, from
> ever
> responding to them.  I shouldn't even be writing this warning to
> you...

Oh, sorry for my weak memory to switch to another account when writing
a new emails.

Here what I would like to share (original + update + Cc dmaengine@):

Recently I've met an issue which, I (wrongly) guess, requires
architectural changes in virt-chan API.

The setup. UART (16750) with DMA engine (drivers/dma/hsu/) on Intel
Edison board (Tangier SoC). Both are different PCI devices.

HSU DMA Documentation states in particular "
If the UART receives data that does not reach the size of the minimum
bus transfer size, than this data remains in the buffer and is never
delivered to the memory by the DMA.
In order to resolve such potential problem, the UART generates a
timeout interrupt to the DMA. This interrupt is not dependent on the
timeout enable bit in the UART but is always enabled.
Once the DMA receives such an interrupts, it will start emptying the
FIFO and assert its own timeout interrupt to the CPU."

UART documentation states
"Receiver Timeout Interrupt
This interrupt only occurs in FIFO mode."

Our current DMA <-> UART work flow relies on UART Timeout Interrupt,
which is not happen in this case.

Let's consider simple transfer of 4696 bytes with internal loopback

...

R 29.927704 0xff010404 0x00000004 <- IRQ from DMA
R 29.927714 0xff010580 0x000f0001 <- Descriptor done
R 29.927729 IIR 0xc1 <- dup for UART!
R 29.927912 0xff010404 0x00000008
R 29.927925 0xff0105c0 0x000f0001
R 29.927944 IIR 0xc1

<- start last piece of transfer

W 29.928154 0xff0105c4 0x00000000
W 29.928165 0xff0105c8 0x00000000
W 29.928172 0xff0105d0 0x00000040
W 29.928179 0xff0105d4 0x00000000
W 29.928187 0xff0105e0 0x39be9000
W 29.928195 0xff0105e4 0x00001000 <- expect 4KiB
W 29.928202 0xff0105c8 0x01818101
W 29.928209 0xff0105c4 0x00000003
W 29.928620 0xff010584 0x00000000
W 29.928633 0xff010588 0x00000000
W 29.928640 0xff010590 0x00000040
W 29.928647 0xff010594 0x00000000
W 29.928655 0xff0105a0 0x39412000
W 29.928663 0xff0105a4 0x00000258 <- sent only 600 bytes
W 29.928671 0xff010588 0x01818101
W 29.928678 0xff010584 0x00000001
R 29.933346 0xff010404 0x00000004
R 29.933361 0xff010580 0x000f0001
R 29.933389 IIR 0xc1
R 29.933944 0xff010404 0x00000008 <- DMA IRQ
R 29.933959 0xff0105c0 0x000e0100 <- descriptor timeout
R 29.933992 IIR 0xc1 <- dup!

<- poll timeout in user space since we didn't get last part of data.

R 40.738944 MSR 0xb0

So, interesting combination. But looks like we get a shadow interrupt
from UART with NO_INT bit set.


What DMA Engine API provides us? The callback function and possibility
to call a _tx_status() from it. During completion tasklet the flow
looks like this:
1. Split completed descriptor to local list.
2. Get callback functions for first descriptor in the list.
3. Free the descriptor.
4. Call callback. <<< descriptor related information is gone already!

That means that current work flow for DMA <-> UART is not sufficient
since it doesn't allow caller to get the actual amount of data
transfered.

So, what I see is should be done here in order to fulfill UART needs.
1. We have to handle properly timeout interrupt in the DMA driver and
call completion for the descriptor.
2. Somehow be sure that the descriptor under question is accessible
during callback when _tx_status() is called.
3. Fill residue even for completed descriptor (when cookie is in
DMA_COMPLETE status).

For now on I have no (good) ideas about implementation, nor anything
else in mind how to achieve it.

I would like to hear experienced guys what maybe I missed here or
didn't look at. Any proposals how to get this fixed in generic manner.


-- 
Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
Intel Finland Oy

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux