已有缓冲区时采用Consistent DMA替代Streaming DMA的原因探究
虽然流式DMA映射是内核推荐的通用方案,但在以太网驱动场景下,针对已有缓冲区(如skb)相关的一致性映射使用,通常是基于预分配一致性缓冲区复用的场景,核心原因和优势如下:
极致低延迟与高吞吐需求
对于高性能网卡(如数据中心级以太网适配器),接收/发送路径的延迟和CPU开销是关键指标。预分配的一致性缓冲区无需每次数据包传输都执行dma_map_single()/dma_unmap_single()的映射解映射操作,也省去了流式映射必需的缓存同步步骤(如dma_sync_single_for_cpu()),能显著减少CPU占用,提升数据包处理的吞吐量和响应速度。硬件兼容性约束
部分老旧或特殊的以太网硬件存在限制:比如不支持分散-聚集(Scatter-Gather)DMA,要求缓冲区必须是物理连续的;或者仅能识别特定物理地址范围内的内存。此时预分配的一致性缓冲区(dma_alloc_coherent()可保证物理连续且地址符合要求)是唯一可行的选择——现有skb的内存可能不满足这些硬件要求,只能将skb数据拷贝到一致性缓冲区后再执行DMA传输。驱动逻辑简化
对于嵌入式场景下的简单网卡驱动,优先考虑代码简洁性和维护成本。使用预分配的一致性缓冲区可以规避流式映射中复杂的缓存同步时机控制、映射状态管理等细节,降低驱动开发出错的概率,减少后期维护的工作量。长期复用的环形缓冲区场景
多数以太网驱动采用环形缓冲区(RX/TX Ring)管理数据包,这类缓冲区需要长期、反复被DMA硬件访问。一致性映射的生命周期与缓冲区绑定,一旦分配映射完成即可持续使用,无需每次传输都执行映射操作;而流式映射即便复用缓冲区,每次也需执行缓存同步,效率远低于一致性映射。
需要注意的是:无法直接对已存在的skb缓冲区执行一致性映射——一致性DMA映射的核心API(如dma_alloc_coherent())是内存分配与映射一体的,skb的内存由内核通用分配器管理,无法直接转为一致性映射。实际驱动中看到的一致性映射使用,要么是用预分配缓冲区承接数据后再转为skb,要么是skb的内存本身来自预分配的一致性内存池。
内容的提问来源于stack exchange,提问作者ransh

