转自:http://blog.sina.com.cn/s/blog_4ce016230101hxgd.html
一致性DMA
dma_alloc_coherent(dev, size, &dma_handle, gfp);
流式DMA
dma_map_single(dev, addr, size, direction);
dma_unmap_single(dev, dma_handle, size, direction);
一致性DMA可以认为是“同步的”,就是DMA和CPU之间看到的物理内存是一致的。流式DMA则不然。
DMA操作和CPU之间的主要隔阂就是cache,因为一般来说DMA只操作物理内存,不会动cache,但CPU却首先看到的是L1 L2cache,所以设备驱动就需要调用正确的DMA函数来操作cache。拿网卡收发包为例,假如CPU发包给网卡,那CPU填好skb的数据之后,得先把cache里有关这个skb数据的行给刷到物理内存,否则网卡从物理内存拿到的数据不是真正所要的数据。反之,CPU把skb数据装配好DMA rx descriptor的时候,得先invalid掉这个skb数据在cache里的行。这样DMA把收到的包填到物理内存后再中断告知CPU时,CPU就可以避免从cache拿到关于这个skb的老(脏)数据,而会从物理内存取包而重新建立数据cache。dma_map_single dma_unmap_single做的就是这个事情,它会根据数据的方向来判断该是clean cache还是incalid cache。
那么DMA描述符呢,DMA控制器和CPU都要对DMA描述符做频繁操作,当CPU和DMA需要频繁的操作一块内存区域的时候,一致性DMA映射就比较合适。所以DMA描述符特别适用于一致性DMA。当然,你也可以对DMA描述符用流式操作,但那样开销就比较大了。
顺便说一句,刷cache是比较耗时的,特别是刷的区域比较大的时候。现代的很多处理器,CPU和DMA控制器之间从硬件上就能保证cache一致性,如ARM的ACP功能,这样像dma_map_single只是返回物理地址,而dma_unmap_single什么都不做。极大的提高了系统性能。
阅读(2004) | 评论(0) | 转发(0) |