Reputation:
Following the text at https://www.kernel.org/doc/Documentation/DMA-API.txt a few inlined questions
Part Ia - Using large dma-coherent buffers
------------------------------------------
void *
dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
Consistent memory is memory for which a write by either the device or
the processor can immediately be read by the processor or device
without having to worry about caching effects. (You may however need
to make sure to flush the processor's write buffers before telling
devices to read that memory.)
Q1. Is it safe to assume that the area allocated is cacheable ? As the last line state that flushing is required
Q1a. Does this API allocate memory from lower 16MB which is considered DMA safe.
dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
Maps a piece of processor virtual memory so it can be accessed by the
device and returns the physical handle of the memory.
The direction for both api's may be converted freely by casting.
However the dma_ API uses a strongly typed enumerator for its
direction:
DMA_NONE no direction (used for debugging)
DMA_TO_DEVICE data is going from the memory to the device
DMA_FROM_DEVICE data is coming from the device to the memory
DMA_BIDIRECTIONAL direction isn't known
Q2. Does the DMA_XXX options direct change of Page Attributes for the VA=>PA mapping. Say DMA_TO_DEVICE would mark the area as non-cacheable ?
Upvotes: 1
Views: 3123
Reputation: 2470
It says "without having to worry about caching effects". That means dma_alloc_coherent()
returns uncacheable memory unless the architecture has cache coherent DMA hardware so the caching makes no difference. However being uncached does not mean that writes do not go through the CPU write buffers (i.e. not every memory access is immediately executed or executed in the same order as they appear in the code). To be sure that everything you write into memory is really there when you tell the device to read it, you will have to execute a wmb()
at least. See Documentation/memory-barriers.txt for more information.
dma_alloc_coherent()
does not return memory from the lower 16 MB, it returns memory that is accessible by the device inside the addressable area specified by dma_set_coherent_mask()
. You have to call that as part of the device initialization.
Cacheability is irrelevant to dma_map_*()
functions. They make sure that the given memory region is accessible to the device at the DMA address they return. After the DMA is finished dma_unmap_*()
is called. For DMA_TO_DEVICE the sequence is "write data to memory, map(), start DMA, unmap() when finished", for DMA_FROM_DEVICE "map(), start DMA, unmap() when finished, read data from memory".
Cache makes no difference because usually you are not writing or reading the buffer while it is mapped. If you really have to do that you have to explicitly dma_sync_*()
the memory before reading or after writing the buffer.
Upvotes: 7