Chinaunix首页 | 论坛 | 博客
  • 博客访问: 804898
  • 博文数量: 127
  • 博客积分: 2669
  • 博客等级: 少校
  • 技术积分: 1680
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-23 11:39
文章分类

全部博文(127)

文章存档

2014年(5)

2013年(19)

2012年(25)

2011年(9)

2010年(25)

2009年(44)

分类:

2012-12-14 13:54:41

继续分析Async_tx的头文件,

/* on architectures without dma-mapping capabilities we need to ensure  * that the asynchronous path compiles away  */ #ifdef CONFIG_HAS_DMA #define __async_inline #else #define __async_inline __always_inline #endif

在没有DMA映射的架构下,使用宏值来保证编译成inline???

/**  * dma_chan_ref - object used to manage dma channels received from the  *   dmaengine core.  * @chan - the channel being tracked  * @node - node for the channel to be placed on async_tx_master_list  * @rcu - for list_del_rcu  * @count - number of times this channel is listed in the pool  * (for channels with multiple capabiities)  */ struct dma_chan_ref {  struct dma_chan *chan;  struct list_head node;  struct rcu_head rcu;  atomic_t count; };

这里面有2个概念,一个是dma channels,一个是dmaengine。dma通道可以认为是逻辑上的,也可以认为就是对应了CPU上的一个物理的DMA通道。通常CPU和DMA芯片之间有多个通道连接,每一个通道都有硬件厂商定义的DMA能力。比如可以有0、1、2、3,共4个通道,CPU厂商定义4个通道都可以进行DMA内存搬运操作,并且0、1通道有DMA raid能力,这里主要指得是raid5、raid6的异或和PQ计算能力。

Async_tx起的是一个隔离底层硬件差异的中间层,不管底层的CPU是Intel的,还是AMD,还是MIPS的,只要底层驱动提供了通道抽象的实现,上层应用,这里主要是指的raid5、6就不需要修改代码,直接使用Async_tx的API就可以完成raid栈的功能。这里还要提醒,就算底层没有DMA能力,Async_tx也可以自动识别,自动使用CPU来直接memcpy或进行xor计算。

另外Async_tx还提供了通道切换的服务,含义是一些特定的操作,比如raid5的memcpy-->xor-->memcpy操作,这个是必须是连续执行的,后面的操作依赖前一步的结果,这个时候,上层不必关心底层的细节,Async_tx可以将这些操作串成一个chain,一次发送到同一个通道上执行。而由于通道需要重新配置才能提供不同的能力,这个通道切换就由底层提供回调接口,在Async_tx框架内自动执行。

/**  * async_tx_flags - modifiers for the async_* calls  * @ASYNC_TX_XOR_ZERO_DST: this flag must be used for xor operations where the  * the destination address is not a source.  The asynchronous case handles this  * implicitly, the synchronous case needs to zero the destination block.  * @ASYNC_TX_XOR_DROP_DST: this flag must be used if the destination address is  * also one of the source addresses.  In the synchronous case the destination  * address is an implied source, whereas the asynchronous case it must be listed  * as a source.  The destination address must be the first address in the source  * array.  * @ASYNC_TX_ACK: immediately ack the descriptor, precludes setting up a  * dependency chain  * @ASYNC_TX_FENCE: specify that the next operation in the dependency  * chain uses this operation's result as an input  */ enum async_tx_flags {  ASYNC_TX_XOR_ZERO_DST  = (1 << 0),  ASYNC_TX_XOR_DROP_DST  = (1 << 1),  ASYNC_TX_ACK   = (1 << 2),  ASYNC_TX_FENCE   = (1 << 3), };

4个枚举变量,作为异步调用的必填的flag,每个都必须在合适的情况下调用,

* @ASYNC_TX_XOR_ZERO_DST: 该标记必须在xor操作下使用,当目的地址不是源地址的时候。在异步情况下,清0是隐含的,而同步模式下需要清0目的块。这也很显然,先把目的地址清个0,然后将计算出来的xor值拷到目的地址中去,避免一些可能错误。

* @ASYNC_TX_XOR_DROP_DST: 该标记必须在当目的地址也是源地址的情况下使用。在同步执行模式下,这个是隐含操作。但是在异步执行模式下,必须将目的地址放到为源地址列表。而且目的地址必须是源地址列表中的第一个。

* @ASYNC_TX_ACK: 立即应答描述符,组织设置关联chain。也就是最常用的,如果没有什么关联关系的操作,一般就设置为这个flag

* @ASYNC_TX_FENCE: 制定下一个依赖操作使用本次操作的结果作为输入

 

菊子曰 这就是啦!
阅读(1310) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~