DMA映射

1.一致性映射:关闭cache,但写缓冲可以在,使用方式:dma_alloc_writecombine 分配出来的内存不使用缓存cache,但是会使用写缓冲区。而 dma_alloc_coherent  则二者都不使用。

2.流式映射:

在流式DMA映射场合,DMA传输通道所使用的缓冲区往往不是由当前驱动程序自身分配的,而且往往每次DMA传输都会重新建立一个流式映射的缓冲区。此外,由于无法确定外部模块传入的DMA缓冲区的映射情况,所以设备驱动程序必须小心地处理可能会出现的cache一致性问题。

(1)在向内传输(rx)时,DMA设备将数据写入内存后,DMAC将向CPU发出中断请求,在RX ISR中使用该内存之前,需要先InvalidateD-Cache(sync_single_for_cpu)使cache无效重填(refill),此时CPU通过高速缓存cache获得的才是最新的数据。

/* 确定中断是由对应的设备发来的*/

dma_unmap_single(dev->pci_dev->dev,dev->dma_addr,
dev->dma_size,dev->dma_dir);

/* 释放之后,才能访问缓冲区,把它拷贝给用户 */

(2)在向外传输(tx)时,一种可能的情形是CPU构造的本地协议栈反馈包还在D-Cache中,故在send调用中需要先Flush D-Cache(sync_single_for_device)将数据写回(write back)到内存,使DMA缓存更新为最新鲜的待发送数据再启动DMA TX trigger。

说白了就是接收清cache操作sync_single_for_cpu,发送刷cache操作sync_single_for_device

CPU的读/写用的是不同的cache(读用的是cache,写则用的是write buffer),所以建立流式DMA映射需要指明数据在DMA通道中的流向,以便由内核决定是操作cache还是write buffer。

 

3.分散/聚集DMA映射(scatter/gather map)

到目前为止,对DMA操作时缓冲区的映射问题的讨论仅限于单个缓冲区,接下来将讨论另一种类型的DMA映射——分散/聚集映射。

分散/聚集映射通过将虚拟地址上分散的多个DMA缓冲区通过一个类型为struct scatterlist的数组或链表组织起来,然后通过一次的DMA传输操作在主存RAM和设备之间传输数据。可以类比WinSock中WSA系列API提供的Scatter/GatherI/O特性。

 

上图显示了主存中三个分散的物理页面与设备之间进行的一次DMA传输时分散/聚集映射示意。其中单个物理页面与设备之间可以看做是一个单一的流式映射,每个这样的单一映射在内核中有数据结构strcut scatterlist来表示。

如果从CPU的角度来看这种分散/聚集映射,它对应的需求时三块数据(分别存放在三段分散的虚拟地址空间中)需要和设备进行交互(发送或者接收),通过建立struct scatterlist类型的数组/链表在一次DMA传输中完成所有的数据传输。这样,通过减少重复的DMA传送请求来提高效率。

通过上面的讨论可知,分散/聚集映射本质上是通过一次DMA操作把主存中分散的数据块在主存与设备之间进行传输,对于其中的每个数据块内核都会建立对应一个流式DMA映射。但是对于MIPS、ARM平台而言,还是需要通过软件来保证cache的一致性问题。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值