Handling DMA completion timeouts

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

 



Hey all,

I sent nearly this same message to the "kernelnewbies" mailing list
(kernelnewbies@xxxxxxxxxxxxxxxxx) in hopes to get some response there.
I haven't heard anything back and I see this mailing list referenced
in various documentation. I hope this message is appropriate for this
audience.

As a newbie, I'm trying to figure out how to properly deal with
timeouts after dma_engine_submit(). My intent is to build a new
"device" driver using Xilinx's AXIDMA driver linked below. Xilinx
provides a couple references called "dma-proxy" and "axidmatest" that
exercise the DMA Engine interop with their driver. I think I
understand this layering correctly, but I'm pretty new to the DMA
Engine framework.

xilinx dma driver:
https://github.com/Xilinx/linux-xlnx/blob/master/drivers/dma/xilinx/xilinx_dma.c
dma-proxy driver:
https://github.com/Xilinx-Wiki-Projects/software-prototypes/blob/master/linux-user-space-dma/Software/Kernel/dma-proxy.c
xilinx dmatest driver:
https://github.com/Xilinx/linux-xlnx/blob/master/drivers/dma/xilinx/axidmatest.c

Using the referenced "dma-proxy" as an example, I'm tracing the case
where there is a timeout. In my "device" case, I want some data from a
DMA slave (DEV_TO_MEM) but it may never come. I'm mentally treating
this as a "socket" but I understand I may have retool my mental
model...

First, this chain eventually resolves into `dma_engine_submit()` via
dma_device->device_prep_slave_sg():
-----------------------------------------------------------------

(~ https://github.com/Xilinx-Wiki-Projects/software-prototypes/blob/master/linux-user-space-dma/Software/Kernel/dma-proxy.c#L198)

sg_init_table(..., 1);
sg_dma_address(... ) = foo.dma_handle;
sg_dma_len(...) = foo.length;
chan_desc = dma_device->device_prep_slave_sg(..., ..., 1, ..., ..., NULL);

if (! chan_desc) {
     printk(KERN_ERR "dmaengine_prep*() error\n");
else { ... }


Then, the driver waits for the completion and prints an error if it
cannot complete:
-------------------------------------------------------------------------------------------------------------------

unsigned long timeout = msecs_to_jiffies(3000);
timeout = wait_for_completion_timeout(foo.cmp, timeout);
status = dma_async_is_tx_complete(..., ..., NULL, NULL);

if (timeout == 0)  {
     printk(KERN_ERR "DMA timed out\n");
}
else { ... }

======

I cannot figure out what to do in the case of a timeout. It appears
descriptors (`chan_desc`) are being leaked when completion cannot be
completed. I see some patches to make the list of descriptors larger
but it appears the default/configured is 255. So if I sit and timeout
for 3sec * 255, I run out of descriptors and that DMA engine instance
is no longer usable. Both this dma-proxy and dmatest driver don't seem
to handle any sort of failure cleanup.

I hope someone can point me in the right direction so I can timeout
nicely. Maybe I need to switch to polling or something like this. Any
information is helpful.

Thanks!




[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux