Linux DMA开发指南(一)

  在以往,一个硬件设备要去读写内存,往往需要CPU参与搬运数据,以读内存为例,CPU会先将数据从内存中读取过来之后,再通过总线或寄存器送给设备。这种方式显而易见,不仅占用了大量CPU资源的同时,还会大大降低设备的吞吐量,后来为了缓解这个问题,DMA机制出现了。

  DMA的核心思想是:在数据的传输阶段,设备可以在DMA控制器的协助下直接访问内存,而不再需要CPU去帮忙读数据或者写数据了,CPU要做的就是在传输开始前进行一些配置即可。通过这种方式,大大降低了CPU占用率的同时,还提升了自身设备的吞吐量。

  从表面上来看,cache的引入本身是为了提升CPU读写的性能,DMA的引入也是为了提升设备性能,但是当两者一起使用的时候,可能会事与愿违。想象一下一个场景,现在CPU更新了一组数据,由于cache的存在,CPU会暂时把数据更新在cache中,此时DMA设备屁颠屁颠的去内存中读取数据,发现读到的数据怎么是老的数据,这就出现了缓存不一致的问题。

  那么怎么解决这个问题呢,目前最常见的两种方式,缓存刷新与缓存失效。当CPU刚刚修改完数据并即将由DMA设备读取时,通过缓存刷新能将cache中的脏数据写回内存中,DMA设备就能读到最新的数据。而当DMA设备向内存写了的数据,CPU随后需要去读,则需要通过缓存失效使CPU cache中的旧数据失效,从而让CPU从内存中读取设备刚刚写入的新内容。

  了解了缓存一致性问题和DMA机制后,在实际的 Linux 驱动开发中,开发者该如何正确使用cache和DMA设备并避免这类陷阱?Linux 内核早已意识到这一问题,并提供了一套完整的
DMA 映射(DMA mapping)API,专门用于在启用缓存的系统上安全地进行 DMA 操作。

赞(0)
未经允许不得转载:小狮博客 » Linux DMA开发指南(一)
分享到: 更多 (0)

联系我们