DMA 属性

本文档描述了在 linux/dma-mapping.h 中定义的 DMA 属性的语义。

DMA_ATTR_WEAK_ORDERING

DMA_ATTR_WEAK_ORDERING 指定对映射的读取和写入可能是弱排序的,也就是说,读取和写入可能会互相穿过。

由于平台可以选择是否实现 DMA_ATTR_WEAK_ORDERING,那些不实现的平台将简单地忽略该属性并表现出默认行为。

DMA_ATTR_WRITE_COMBINE

DMA_ATTR_WRITE_COMBINE 指定对映射的写入可以被缓冲以提高性能。

由于平台可以选择是否实现 DMA_ATTR_WRITE_COMBINE,那些不实现的平台将简单地忽略该属性并表现出默认行为。

DMA_ATTR_NO_KERNEL_MAPPING

DMA_ATTR_NO_KERNEL_MAPPING 允许平台避免为分配的缓冲区创建内核虚拟映射。在某些架构上,创建这样的映射是一项不简单的任务,并且会消耗非常有限的资源(例如内核虚拟地址空间或 DMA 一致地址空间)。使用此属性分配的缓冲区只能通过调用 dma_mmap_attrs() 传递给用户空间。通过使用此 API,您可以保证不会取消引用 dma_alloc_attr() 返回的指针。您可以将其视为一个 cookie,必须将其传递给 dma_mmap_attrs() 和 dma_free_attrs()。请确保这两个函数在每次调用时也设置了此属性。

由于平台可以选择是否实现 DMA_ATTR_NO_KERNEL_MAPPING,那些不实现的平台将简单地忽略该属性并表现出默认行为。

DMA_ATTR_SKIP_CPU_SYNC

默认情况下,dma_map_{single,page,sg} 函数系列将给定缓冲区从 CPU 域传输到设备域。一些高级用例可能需要在多个设备之间共享缓冲区。这需要为每个设备单独创建一个映射,通常通过为给定缓冲区多次调用 dma_map_{single,page,sg} 函数,并将设备指针指向参与缓冲区共享的每个设备来执行。第一次调用将缓冲区从“CPU”域传输到“设备”域,这将同步给定区域的 CPU 缓存(通常意味着缓存已刷新或失效,具体取决于 DMA 方向)。但是,后续对其他设备调用 dma_map_{single,page,sg}() 将对 CPU 缓存执行完全相同的同步操作。CPU 缓存同步可能是一个耗时的操作,尤其是当缓冲区很大时,因此强烈建议尽可能避免它。DMA_ATTR_SKIP_CPU_SYNC 允许平台代码跳过给定缓冲区的 CPU 缓存同步,假设它已经传输到“设备”域。此属性也可以用于 dma_unmap_{single,page,sg} 函数系列,以强制缓冲区在释放其映射后仍保留在设备域中。请谨慎使用此属性!

DMA_ATTR_FORCE_CONTIGUOUS

默认情况下,DMA 映射子系统允许从单个页面组装由 dma_alloc_attrs() 函数分配的缓冲区,如果它可以作为连续块映射到设备 DMA 地址空间中。通过指定此属性,强制分配的缓冲区在物理内存中也是连续的。

DMA_ATTR_ALLOC_SINGLE_PAGES

这是对 DMA 映射子系统的提示,表明可能不值得花费时间尝试以提供更好 TLB 效率的方式分配内存(也就是说,不值得尝试使用更大的页面构建映射)。如果满足以下条件,您可能需要指定此项:

  • 您知道对此内存的访问不会导致 TLB 抖动。您可能知道访问很可能是顺序的,或者它们不是顺序的,但不太可能在可能位于不同物理页面中的许多地址之间来回切换。

  • 您知道访问内存时 TLB 未命中的代价足够小,无关紧要。如果您正在执行解密或解压缩等繁重操作,则可能会出现这种情况。

  • 您知道 DMA 映射是相当短暂的。如果您预计映射的生命周期较短,那么可能值得优化分配(避免使用大页面),而不是获得更大页面带来的轻微性能提升。

设置此提示并不能保证您不会获得大页面,但这表示我们不会那么努力地尝试获取它们。

注意

目前,DMA_ATTR_ALLOC_SINGLE_PAGES 仅在 ARM 上实现,尽管 ARM64 补丁很可能很快就会发布。

DMA_ATTR_NO_WARN

这告诉 DMA 映射子系统抑制分配失败报告(类似于 __GFP_NOWARN)。

在某些架构上,分配失败会向系统日志报告错误消息。尽管这有助于识别和调试问题,但处理失败的驱动程序(例如,稍后重试)对它们没有任何问题,并且实际上可能会用根本不是任何问题的错误消息淹没系统日志,具体取决于重试机制的实现。

因此,这为驱动程序提供了一种在分配失败不是问题且不应干扰日志的调用中避免这些错误消息的方法。

注意

目前,DMA_ATTR_NO_WARN 仅在 PowerPC 上实现。

DMA_ATTR_PRIVILEGED

一些高级外围设备(如远程处理器和 GPU)以特权“管理程序”和非特权“用户”模式访问 DMA 缓冲区。此属性用于向 DMA 映射子系统指示该缓冲区在提升的特权级别完全可访问(并且理想情况下在较低特权级别不可访问或至少只读)。