Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does every dma_map_single call require a corresponding dma_unmap_single?

I'm porting a large code base to a Linux kernel device driver. The ASIC uses a huge number of DMA channels.

I kmalloc memory with GFP_KERNEL|GFP_DMA. Before starting the DMA, I use dma_map_single to get the hardware (physical) memory address to feed to the hardware. (Also does a flush/invalidate the memory from dcache?) I sometimes need CPU access to the data once DMA is complete, but not often. Before I access the data via code, I do a dma_unmap_single to avoid cache coherency issues.

In the cases where I do not ever need CPU access, do I still need to call dma_unmap_single? Should I dma_unmap_single every pointer I dma_map_single? Does dma_map_single consume a resource (e.g., table entry) that dma_unmap_single will release?

The DMA-API.txt isn't clear on good DMA memory hygiene.

Thanks!

like image 814
David Poole Avatar asked Apr 23 '13 14:04

David Poole


People also ask

How to disable SWIOTLB?

There is no way to disable SWIOTLB in the kernel configuration. Since kernel v4. 10, the swiotlb=noforce kernel parameter turns off SWIOTLB and any attempt to use it along with DMA mappings, and the memory allocation is reduced to minimum (and no allocation at all from kernel v5.

How does DMA work in Linux?

Direct memory access, or DMA, is the advanced topic that completes our overview of memory issues. DMA is the hardware mechanism that allows peripheral components to transfer their I/O data directly to and from main memory without the need for the system processor to be involved in the transfer.

Where is memory allocated for DMA?

A DMA buffer can be allocated in two ways: Contiguous Buffer: A contiguous block of memory is allocated. Scatter/Gather: The allocated buffer can be fragmented in the physical memory and does not need to be allocated contiguously.

What is Dma_sync_single_for_cpu?

dma_sync_single_for_cpu() gives ownership of the DMA buffer back to the processor. After that call, driver code can read or modify the buffer, but the device should not touch it. A call to dma_sync_single_for_device() is required to allow the device to access the buffer again.


1 Answers

With dma_map_single you map the memory for DMA transfer. You get the physical pointer to the memory, so the device can DMA to that address.

With dma_unmap_single you unmap the memory mapped above. You should do this when your transfers are over.

You can map a memory region, and use it for multiple DMA transfers and then you unmap when the job is done. Each time you want to access the DMA memory you must synchronize it. If the device is going to access the memory, you should do dma_sync_single_for_device; it the host is going to access the memory, you should do dma_sync_single_for_cpu

like image 131
Federico Avatar answered Sep 24 '22 15:09

Federico