免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 11823 | 回复: 41
打印 上一主题 下一主题

[硬件及驱动] ARMv7中CONFIG_ARM_DMA_MEM_BUFFERABLE的疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-03-11 11:29 |只看该作者 |倒序浏览
Hi All

大家对这个函数应该不陌生
dma_alloc_coherent
对于ARM, 这个函数是分配一块内存,然后把它的属性定义为"coherent",然后这块内存就不需要再做cacle inv/flush的动作了, dma_alloc_coherent实际上使用下面的宏来定义这块coherent属性。

#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
#define pgprot_dmacoherent(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN)
#else
#define pgprot_dmacoherent(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
#endif

#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
#include <asm/barrier.h>
#define __iormb()                rmb()
#define __iowmb()                wmb()
#else
#define __iormb()                do { } while (0)
#define __iowmb()                do { } while (0)
#endif

如果定义CONFIG_ARM_DMA_MEM_BUFFERABLE宏,则dma_alloc_coherent则使用L_PTE_MT_BUFFERABLE来分配这个coherent内存,并且访问外设必须带着mb;
如果不定义这个宏,则使用L_PTE_MT_UNCACHED分配这个coherent内存,并且访问外设不需要带有mb。

我下面有一个例子,在我的ARMv7设置中,TEX=1, 也就是内存的设置需要使用PRRR和NMRR来定义,使能CONFIG_ARM_DMA_MEM_BUFFERABLE后,然后dma_alloc_coherent分配的内存是strong order。这里,我觉得是有疑问的,既然是strong order,这块内存已经确保了访这段内存是顺序的,不会有问题,所以我去掉了mb操作,因此CPU loading下降了,性能也有提高。

因为是V7而且TEX=1, UNCACHED和BUFFERABLE已经失去了它字面的意思。我的疑问是,在CONFIG_ARM_DMA_MEM_BUFFERABLE使能与否的情况下,对应的内存各应该是什么样的呢?因为它决定了这段coherent内存访问是否需要barrier。normal+uncached可以吗?device可以吗?


Thanks

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
2 [报告]
发表于 2014-03-11 13:33 |只看该作者
回复 1# lyl19
armv7的处理与之前的arm架构有些不同,可以看看这个讨论http://www.linuxhorizon.com/9-linux/46cdfaa5c13c1cf3-2.htm
   

论坛徽章:
0
3 [报告]
发表于 2014-03-11 15:41 |只看该作者
本帖最后由 lyl19 于 2014-03-11 16:37 编辑

谢谢了,我看了一下,这个与我的问题还是不太相关。

我这边还有一个发现,前面说使用dma_alloc_coherent分配的空间,在CONFIG_ARM_DMA_MEM_BUFFERABLE的情况下,是strong order类型的,这个时候,假设设备通信时整个系统cpu loading是70%, 如果我去掉mb,因为我觉得在strong order的时候并不需要,这个时候cpu loading变成了65%,并且没有发现异常。

但如果我去掉CONFIG_ARM_DMA_MEM_BUFFERABLE,这个时候,dma_alloc_coherent以L_PTE_MT_UNCACHED的类型来分配consistent内存,最终得到的内存属性为device+shareable,结果发现整个系统cpu loading变成了80%+,

我很疑惑两点。
1. 在使能CONFIG_ARM_DMA_MEM_BUFFERABLE与否的情况下,consistent内存属性到底是什么样的,才能确定是否需要mb,从ARMv7 spec中得到的语句,strong order的可以保证指令顺序,并且保证每条指令到到达设备后下一条指令才执行,所以我认为它不需要mb。但device类型的有一个词是"is permitted to complete before it reach..." ARMv7, section 3.5.6,所以我不确定device类型的是否需要mb。
2. 为什么strong order和device类型的在性能上面有这么大的差别,反而strong order更好于device的。

Thanks

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
4 [报告]
发表于 2014-03-11 19:34 |只看该作者
回复 3# lyl19


    但如果我去掉CONFIG_ARM_DMA_MEM_BUFFERABLE,这个时候,dma_alloc_coherent以L_PTE_MT_UNCACHED的类型来分配consistent内存,最终得到的内存属性为device+shareable,结果发现整个系统cpu loading变成了80%+,

这种情况下你的mb去掉没?

论坛徽章:
0
5 [报告]
发表于 2014-03-11 21:31 |只看该作者
回复 4# arm-linux-gcc


    你好,去掉了的,如果不使能这个宏,io操作默认是不包含wb操作的。

论坛徽章:
0
6 [报告]
发表于 2014-03-11 21:42 |只看该作者
回复 5# lyl19
我还想加一点,我觉得对于dma_alloc_coherent分配的内存,如果是strong order的,我觉得还是有必要在io访问时使用mb, 因为strong order的内存能够保证对它访问的指令是严格顺序的,但不能保证访问它和访问其它类型的mermory的指令的顺序性,这个在ARM spec中有写到。
比如说
A指令访问一个normal memory
B指令访问一个strong order memory。

A指令从program order上来看是位于B前,则B指令有可能在A指令前完成。这样做有风险如果B指令访问外设启动某个硬件操作,但它却依赖A指令的一些结果。

所以我觉得dma_alloc_coherent即使分配的是strong order的memory, io操作的wb也不能缺少,虽然我在测试过程中没有发现问题,反而去掉io操作的wb后性能会有提高。

ARM的指令乱序问题和memory barrier实在是令人头疼。

   

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
7 [报告]
发表于 2014-03-11 23:19 |只看该作者
本帖最后由 arm-linux-gcc 于 2014-03-12 11:47 编辑

关掉CONFIG_ARM_DMA_MEM_BUFFERABLE导致性能降低,应该是和总线竞争有关

使用PRRR和NMRR不是因为TEX为1吧,而是由于SCTLR.TRE为1




论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
8 [报告]
发表于 2014-03-12 21:32 |只看该作者
本帖最后由 arm-linux-gcc 于 2014-03-13 09:45 编辑

我对strong order memory类型的理解
strong order memory是uncacheable + unbufferable + shareable
device memory是uncacheable + bufferable + shareable或uncacheable + unbufferable + unshareable

不管sctlr.tre是0还是1,cache和buffer和share的物理意义仍然就是字面意思




关掉CONFIG_ARM_DMA_MEM_BUFFERABLE,dma内存其实就是strong order类型的内存了,即uncacheable + unbufferable + shareable的
那么当两个core各自读写各自使用dma_alloc_coherent分配到内存的时候,两个core就会存在总线竞争
例如两个core都在做memset:memset的实现其实就是在循环里去对地址赋值,编译出来的汇编代码就是类似下面的
    add r2, r0, r2
1:  str r1, [r0], #4
     cmp r0 r2
     bne 1b
其中只有str这一句是会占用总线的,在其余语句是不会占用总线的(icache没有miss的情况下),由于是uncache的,所以str这一句花的时间会很久,所以绝大部分的开销都在str这一句
因此当两个core都对各自分配到的dma内存都做memset时,就会出现一个core等待另一个core释放总线的情况,于是两个core一起使用dma内存就会使得性能下降,因为很多时间都在等对方

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
9 [报告]
发表于 2014-03-12 21:45 |只看该作者
strong order memory和device memory的区别,应该是和总线竞争时的优先级有关的

论坛徽章:
0
10 [报告]
发表于 2014-03-12 23:10 |只看该作者
本帖最后由 lyl19 于 2014-03-12 23:11 编辑

回复 8# arm-linux-gcc

谢谢,你这个回复中,有一个我还有疑惑

strong order memory是uncacheable + unbufferable + shareable
device memory是uncacheable + bufferable + shareable或uncacheable + unbufferable + unshareable

我认为这是在ARMv6以前存在uncacheable + unbufferable,但在ARMv7中,没有发现有unbufferable的属性,我认为bufferable这个属性只存在于normal + write allocate。

请查看ARMv7 sepc B3.8对ARM memory的描述。
“The B (Bufferable), C (Cacheable), and TEX (Type extension) bit names are inherited from earlier versions
of the architecture. These names no longer adequately describe the function of the B, C, and TEX bits.”


“关掉CONFIG_ARM_DMA_MEM_BUFFERABLE,dma内存其实就是strong order类型的内存了”
非常奇怪的是,在我的系统中,关掉这个宏,最终分配的内存属性为device, 使能这个宏,属性为strong order。所以我奇怪为什么strong order的比device的性能会差,应该是差不多才对。


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP