文章目录
概述
现代计算机系统中,CPU访问内存需要经过Cache,但外部设备通常不感知Cache的存在,因此CPU和外设在访问DMA内存时,必须谨慎处理内存数据的一致性问题。为了处理这种一致性问题,同时为了兼顾多种设备类型,Linux系统会采用不同的规则来映射DMA内存,开发者遵循这套规则对DMA内存进行操作。
DMA与Cache一致性
DMA内存中的数据会涉及到CPU和设备的共同访问,区别在于CPU通常经过Cache访问内存,但常规的设备通常不会感知Cache的存在。因此,CPU写入的数据可能因为还存在Cache中而未及时刷入内存,从而导致设备没有DMA到最新的数据;反过来,设备已经向设备DMA了新的数据,但CPU可能仍然在使用Cache中旧的数据。
解决这种DMA与Cache间数据一致性的方法通常有两种,一种是设备硬件支持Cache一致性协议;另外一种就是软件通过同步操作来保证数据一致性。根据硬件是否支持Cache一致性,可以将设备分成两类:
- cache coherence设备:设备之间的读写不需要关心cache的一致性问题,硬件将确保数据一致,比如连接在ARM CCI端口上的设备就是cache coherence设备;
- non-coherence设备:需要额外的软件操作(flush/invalidate)等操作来确保数据一致;
DMA映射类型
Linux系统支持两种DMA映射类型:一致性DMA映射(Consistent DMA Mapping)和流式DMA映射(Streaming DMA Mapping)。二者的核心差异在于:
- 一致性DMA映射情况下,无论是CPU还是设备,在访问DMA内存时,全程都不使用Ca