The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
A dma_addr_t is an address for the device, not a CPU pointer—and it may not match the CPU physical address. Choose a coherent allocation when the CPU and device share a persistent control structure; use a streaming mapping for a transfer buffer whose ownership moves between them. The right choice depends on the device protocol and who accesses the memory when.
What a DMA address represents
The DMA API gives a device an address it can use to access memory. That device-facing address can be translated by an IOMMU or another platform mechanism, so it is not safe to treat it as a CPU physical address or dereference it from the CPU. The Linux DMA API reference puts it plainly: “A CPU cannot reference a dma_addr_t directly because there may be translation between its physical address space and the DMA address space.”
In driver code, keep the CPU-accessible pointer and the device-facing DMA address conceptually separate. Pass the latter to the hardware; access memory through the appropriate CPU pointer.
Coherent allocation or streaming mapping?
| Decision point | Coherent allocation | Streaming mapping |
|---|---|---|
| Typical use | Shared control structures, such as descriptor rings or mailbox structures | Transfer buffers, such as network or storage data |
| Typical lifetime | Allocated during device setup and freed at teardown | Mapped for a transfer and unmapped after completion, or retained and synchronized for reuse |
| Visibility and ownership | CPU and device updates are visible without explicit software cache-flush calls | Direction and CPU/device ownership transitions must be handled through the mapping and synchronization APIs |
| Common interfaces | dma_alloc_coherent() and dma_free_coherent(); dma_pool for many small coherent regions |
dma_map_single() and dma_unmap_single(), page or scatter/gather mapping variants, and synchronization calls when reusing a mapping |
These are common patterns, not rigid categories. The protocol and access pattern determine which model is appropriate.
#1 Best Overall
Example: a persistent descriptor ring
A descriptor ring is control data that the CPU and device may access throughout the device’s operation. A coherent allocation is often a natural fit because both sides need to observe updates without explicit cache-flush calls. However, visibility does not guarantee ordering: if the device must see descriptor fields in a particular sequence, the driver still needs the appropriate memory barriers.
Example: a transfer buffer
A buffer used for a particular network or storage transfer is a typical streaming-mapping candidate. The driver maps it with the direction that matches the data flow, gives the DMA address to the device, and unmaps it after completion—or retains the mapping and performs the required synchronization before changing which side owns the data.
Rank #2
Set addressability before using DMA
Tell the kernel what address width the device can handle before starting DMA. The Linux device-driver guide describes using dma_set_mask_and_coherent() for devices with the same limits for streaming and coherent DMA. Check its return value: if the requested mask is unsupported, the driver must not assume DMA will work. When the device has different limits for streaming and coherent addresses, set the masks separately as appropriate.
Implement streaming mappings safely
Check for mapping failure
A streaming map can fail if the device or bus cannot address the buffer and the platform cannot supply a suitable IOMMU mapping or bounce buffer. Check the result with dma_mapping_error() before giving the address to hardware, and handle failure as a normal error path.
Match direction to data flow
DMA_TO_DEVICE: memory to device.DMA_FROM_DEVICE: device to memory.DMA_BIDIRECTIONAL: data may flow both ways, or the direction is not known.
Choose based on what the device actually does with the buffer, not on a convenient label in the driver.
Transfer ownership and synchronize reused mappings
For a retained streaming mapping, synchronize after the CPU’s final writes and before handing the buffer to the device. Before the CPU reads data the device may have changed, synchronize back to CPU ownership. Bidirectional mappings require transitions in both directions. If unmapping ends the mapping, use parameters that match the original map. The API also provides dma_need_sync() to indicate whether explicit synchronization is needed on the platform.
Rank #4
Use a mapping form that matches the memory
dma_map_single() is not the right description for discontiguous scatter/gather memory; use the scatter/gather mapping API for multiple segments. Kernel virtual contiguity alone does not establish physical contiguity. An IOMMU may relax some physical-address constraints, but a portable driver must not assume one is present.
On non-coherent systems, cache maintenance operates at cache-line granularity. Sharing cache lines unsafely can affect data beyond the intended buffer; the DMA API reference recommends page-bounded regions when the driver cannot safely account for cache-line boundaries. Follow the target platform’s constraints.
Best Value
Keep allocation and mapping costs in view
Many small coherent regions
Coherent allocations can consume page-scale resources even when each requested region is small. For many small descriptors or buffers, consider combining allocations where suitable or using dma_pool.
High-rate, short-lived transfers
Mapping overhead can be a meaningful part of a short request’s lifetime in throughput-sensitive paths. The API exposes dma_max_mapping_size() and dma_opt_mapping_size(); the reference suggests considering the optimal size as a limit for streaming mappings when splitting the work has no significant penalty. These values and trade-offs are platform-specific, not universal thresholds or benchmark results.
Quick Recap
Driver checklist
- Configure the device’s streaming and coherent DMA address limits before using DMA, and check whether the requested mask is supported.
- Choose coherent memory for suitable shared control structures or streaming mappings for transfer buffers according to the protocol and ownership pattern.
- For streaming mappings, select the actual data direction and check every mapping result with
dma_mapping_error(). - Synchronize retained mappings at each CPU/device ownership handoff; unmap with parameters matching the original mapping when the transfer is finished.
- Use scatter/gather interfaces for discontiguous segments, and do not rely on an IOMMU being available.
- For the kernel version you target, consult its matching DMA API HOWTO and API reference; details can change between kernel versions.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.

