Re: [PATCH v2 1/4] dma-mapping: Add devm_ interface for dma_map_single()

From: Eli Billauer
Date: Sat Jun 07 2014 - 08:36:47 EST


Hello Shuah,


We agree that the streaming API was originally *intended* for short map-unmap DMA sessions, and that dma_alloc_noncoherent() was the *intended* API for those who want to hold the DMA during a device's lifetime.

We also agree that on some platforms, DMA mappings are precious, and therefore any driver should unmap a region as soon as it's not needed anymore.

But if we stick to the citation you gave, it says "...unmapped right after it (unless you use dma_sync_* below)". So even in the streaming API's definition, there's an understanding, that the "streaming" DMA buffer can be held for more than a single session. And a good sync tool for that is made available.

Using cross-reference on Linux' code, I get a strong impression, that dma_alloc_NONcoherent() is pretty much unused (I counted 8 drivers). The streaming API's sync functions are heavily used, on the other hand. So one gets a hunch, that there's a lot of use of the streaming API in the kernel tree for long-term DMA mappings.

This wasn't the original intention -- we agree on that. But why is it wrong? Assuming that a driver needs to hold a DMA mapping for a long while, why does it matter if it was done with dma_alloc_noncoherent() or with dma_map_*()? They are equally wasteful, aren't they?

Why maintaining two API sets doing the same thing? Or is there a subtle functional difference I'm not aware of?

Thanks,
Eli



On 06/06/14 20:02, Shuah Khan wrote:

dma_map_single() and dma_unmap_single() are streaming DMA APIs. These
are intended for one DMA transfer and unmapped right after it is done.

dma buffers are limited shared resources for streaming that are
shared by several drivers. Hence the need for use and release
model.

Please refer to the Using Streaming DMA mappings in DMA-API-HOWTO.txt

"- Streaming DMA mappings which are usually mapped for one DMA
transfer, unmapped right after it (unless you use dma_sync_* below)
and for which hardware can optimize for sequential accesses.

This of "streaming" as "asynchronous" or "outside the coherency
domain".

Good examples of what to use streaming mappings for are:

- Networking buffers transmitted/received by a device.
- Filesystem buffers written/read by a SCSI device."


If I understand your intended usage correctly, you are looking to
allocate and hold the buffers for the lifetime of the driver. For
such cases, dma_alloc_*() interfaces are the ones to use.

Please also refer to DMA-API.txt as well. Hope this helps.

-- Shuah



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