linux内核中的一致性DMA与流式DMA

在Linux内核中,一致性DMA(Coherent DMA) 和流式DMA(Streaming DMA) 是两种不同的DMA映射方式,主要区别在于缓存一致性的处理方式:

  1. 一致性DMA(Coherent DMA)

特点:

· 缓存一致性:CPU和DMA设备看到的内存内容总是保持一致的

· 硬件支持:通常需要硬件(如CPU、总线、DMA控制器)支持缓存一致性协议

· 性能开销:由于需要维护一致性,可能有额外的性能开销

使用场景:

· 小数据频繁访问:设备控制块、状态寄存器等

· 双向访问:CPU和设备都需要频繁读写同一内存区域

· 长时间映射:映射持续时间较长

常用API:

c 复制代码
void *dma_alloc_coherent(struct device *dev, size_t size,
                         dma_addr_t *dma_handle, gfp_t flag);
void dma_free_coherent(struct device *dev, size_t size,
                       void *cpu_addr, dma_addr_t dma_handle);
  1. 流式DMA(Streaming DMA)

特点:

· 软件管理一致性:需要显式调用API来同步缓存

· 性能更好:没有持续的一致性维护开销

· 更灵活:可以映射任意已有的内存缓冲区

使用场景:

· 大数据传输:网络数据包、磁盘I/O缓冲区

· 单向传输:主要是CPU→设备或设备→CPU的数据流

· 短时映射:映射后立即使用,完成后取消映射

常用API:

c 复制代码
// 映射单个缓冲区
dma_addr_t dma_map_single(struct device *dev, void *ptr,
                          size_t size, enum dma_data_direction dir);

// 取消映射
void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
                      size_t size, enum dma_data_direction dir);

// 分散/聚集映射(scatter-gather)
int dma_map_sg(struct device *dev, struct scatterlist *sg,
               int nents, enum dma_data_direction dir);
  1. 关键区别对比

特性 一致性DMA 流式DMA

缓存一致性 自动保证 需要手动同步

性能开销 较高 较低

内存分配 专用分配 可映射任意内存

使用复杂度 简单 较复杂

硬件要求 需要硬件支持 无特殊要求

适用数据 小数据、频繁访问 大数据、一次性传输

  1. 缓存同步问题

流式DMA需要显式同步:

c 复制代码
// 数据从CPU到设备(CPU写,设备读)
dma_map_single(dev, buf, size, DMA_TO_DEVICE);
// 内核会确保CPU写入的数据刷新到内存

// 数据从设备到CPU(设备写,CPU读)
dma_addr_t dma_handle = dma_map_single(dev, buf, size, DMA_FROM_DEVICE);
// 设备写入数据后
dma_unmap_single(dev, dma_handle, size, DMA_FROM_DEVICE);
// 内核会使CPU缓存失效,确保CPU读取最新数据
  1. 实际选择建议

使用一致性DMA当:

· 硬件支持且性能可接受

· 数据结构需要被CPU和设备频繁交替访问

· 不想处理复杂的缓存同步逻辑

使用流式DMA当:

· 需要最佳性能

· 传输大量数据

· 硬件不支持缓存一致性

· 愿意处理显式的缓存同步

  1. 现代发展

随着硬件发展,一致性DMA越来越普遍,特别是:

· ARM体系中的DMA coherent pool

· 设备树中的dma-coherent属性

· IOMMU/SMMU的支持使得一致性映射更高效

但流式DMA仍然在性能关键场景中占据重要地位,特别是在网络、存储等高性能I/O路径中。

相关推荐
apcipot_rain3 小时前
C++转Java日记(04)
java·开发语言·c++
wuyk5553 小时前
Keil工具链-第05讲-启动文件与__main到底做了什么
c语言·stm32·单片机·嵌入式硬件·物联网
云和数据.ChenGuang4 小时前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
2035去旅行6 小时前
bootcmd 详细讲解
linux·嵌入式·arm·soc
陈希1237 小时前
Linux 防火墙配置实战:firewalld、iptables 与云安全组
linux·运维·服务器
蜗牛一步步往上爬7 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
女神下凡7 小时前
芯参谋(95):嵌入式文件系统_开发指南
linux·服务器·arm开发·驱动开发·设计规范
艺杯羹8 小时前
Windows原生软件锁设计:从暴力杀进程丢数据到零轮询事件驱动架构
windows·系统架构·开源·开源软件·内存管理·开源协议
shijuejianceliu8 小时前
传统规则视觉与嵌入式AI智能相机的技术差异
人工智能·嵌入式硬件·视觉检测·相机
张张123y9 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent