免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: platinum
打印 上一主题 下一主题

关于 vmalloc 的几点疑惑…… [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-05-17 10:54 |只看该作者
原帖由 zx_wing 于 2009-5-16 23:30 发表

有。DMA需要的内存有专门的函数分配,不会直接使用vmalloc/kmalloc或xxx_pages这样的函数


看来Linux的实现差异和Solaris很大的,Solaris有专门的DMA内存分配函数,保证连续物理内存。

但Solaris的不连续物理内存的分配函数也可以使用,任意不连续物理内存用做DMA时,都通过调用一个单独的DMA函数来分析这片内存区域,看它是由多少个连续物理内存组成的,返回每个连续物理内存的地址。

简单的说,当一片内核内存不保证物理内存连续时,我们可以调用该函数后就能得到一个连续物理内存组成的scat-gather list, 然后,接下来对这个sg list中的每个连续物理内存做DMA就可以了。

我觉得Linux用vmalloc分配的内存完全可以用类似的方法作为DMA内存使用。

[ 本帖最后由 Solaris12 于 2009-5-17 10:57 编辑 ]

论坛徽章:
0
12 [报告]
发表于 2009-05-17 11:18 |只看该作者
对于scatter/gather模式,在这里我理解是要看硬件设备是否支持,否则一
次 DMA 传多个不连续的页面,也没有什么意义吧?还有所谓 DMA 的支持函数,
我看到的都是内部实际调用的 __get_free_pages() 等函数,如 dma_pool_alloc()
/ dma_alloc_coherent()  函数。前者先在 dma pool list cache 中查找,
找不到则调用了 pool_alloc_page(),而在这个函数中调用了 dma_alloc_coherent()
->__get_free_pages() 从而得到页面。在某些体系下 dma_alloc_coherent() 则
直接调用了 alloc_pages() 来分配页面。


如果这么说的话,那么和 WINDOWS 提供的 MDL 应用于 scatter/gather 的 DMA
方式应该是一个意思。DMA controller 用 SCATTER_GATHER_LIST 标识相关页面,
在 DMA_OPERATIONS 中由 GetScatterGatherList->PDRIVER_LIST_CONTROL
的回调函数处理 SCATTER_GATHER_LIST 的相关页面。而 linux 的 DMA 内存分配函
数我没有仔细看,只是知道它内部调用了 __get_free_pages() / alloc_pages() 等函数。
了解的可以说一下。

[ 本帖最后由 sinister 于 2009-5-17 14:40 编辑 ]

论坛徽章:
0
13 [报告]
发表于 2009-05-17 11:18 |只看该作者
看了大家的讨论受益匪浅啊

论坛徽章:
0
14 [报告]
发表于 2009-05-17 11:42 |只看该作者
原帖由 sinister 于 2009-5-17 11:18 发表
对于scatter/gather模式,在这里我理解是要看硬件设备是否支持,否则一
次 DMA 传多个不连续的页面,也没有什么意义吧?还有所谓 DMA 的支持函数,
我看到的都是内部实际调用的 __get_free_pages() 等函数,如 ...

scatter/gather当然要硬件的支持,也很常用。例如网卡通常会把接收/发送的buffer做成scatter/gather,把页面组织成类似链表的结构,每个页面之间可以不连续。

>>我看到的都是内部实际调用的 __get_free_pages() 等函数,如 dma_pool_alloc()
>>/ dma_alloc_coherent()  函数。前者先在 dma pool list cache 中查找,
>>找不到则调用了 pool_alloc_page(),而在这个函数中调用了 dma_alloc_coherent()
>>->__get_free_pages() 从而得到页面。在某些体系下 dma_alloc_coherent() 函数
>>则调用了 alloc_pages() 来分配页面。

Linux下内存系统只有一套,当然所有内存分配都有要万法归宗。这里说DMA需要专门的函数分配不是说它自己实现了一套内存分配机制,而是说它蕴含了两点暗示:
1)分配连续页面
2)内存的一致性保证。因为DMA不仅仅用在数据发送、接收(这些情况通常不需要内存一致性),还是用在driver向硬件发送/接收控制命令,这种情况下内存一致性就很重要了。

论坛徽章:
0
15 [报告]
发表于 2009-05-17 12:06 |只看该作者
恩,看到 “DMA需要的内存有专门的函数分配” 忽略了后面 “直接” 两字。误解了你的意思。

论坛徽章:
0
16 [报告]
发表于 2009-05-18 14:28 |只看该作者
原帖由 sinister 于 2009-5-16 09:19 发表
vmalloc 应该不能直接为 DMA 申请内存。可以使用 kmalloc 或更低层的函数 alloc_page() /
__get_free_page() 加上 GFP_DMA 标志为 DMA 申请内存。这个标志从 zonelist  的
ZONE_DMA 区域进行分配,以保证物理 ...


ZONE_DMA 是16M以下的物理内存,只是给一些旧的设备,之能访问16M以内的物理内存。现在的pci设备的dma engine都能访问4G以内的内存。
所以分配dma able的内存不需要指定GFP_DMA,否则你可能很快就分配不出内存用于dma了。

论坛徽章:
0
17 [报告]
发表于 2009-05-18 14:47 |只看该作者

回复 #11 Solaris12 的帖子

> 但Solaris的不连续物理内存的分配函数也可以使用,任意不连续物理内存用做DMA时,都通过调用一个单独的DMA
> 函数来分析这片内存区域,看它是由多少个连续物理内存组成的,返回每个连续物理内存的地址。
...
> 我觉得Linux用vmalloc分配的内存完全可以用类似的方法作为DMA内存使用。

在linux kernel里,vmalloc应用场景不多,一般是用于kernel access一些firmware, alloc kernel module之类的。设备做dma的memory最后还是都会通过kmalloc, alloc_page来分配。

Solaris这么作是不是可以一定程度上缓解内存碎片的问题。当kernel运行了较长一段时间后,就很难通过buddy system分配出比较大的连续物理内存。如果通过vmalloc可以分配出地址空间,再通过对vmalloc所对应的物理地址分析,系统还是可以在内存碎片较多的情况下,成功完成一些dma操作(纯粹猜测。。。)

论坛徽章:
0
18 [报告]
发表于 2009-05-18 16:55 |只看该作者
vmalloc慢,一在于分配时可能需要动态建立“高端”页表。再有在运行时,也有可能慢于正常映射,因为vmalloc()建立的页表没有立即更新到进程的“内核页表”中,这"可能"会引起页错,可以参考一下do_page_fault()。

[ 本帖最后由 raise_sail 于 2009-5-18 17:04 编辑 ]

论坛徽章:
0
19 [报告]
发表于 2009-05-18 19:09 |只看该作者
vmalloc 和 kmalloc 比慢多了。
后者是基于SLAB做的。在不断的申请释放时候是很快的。

vmalloc和用户程序的malloc类似,通过缺页建立物理页。慢多了。但vmalloc时候分配大的内存,因为不要求连续。

论坛徽章:
0
20 [报告]
发表于 2009-05-18 20:12 |只看该作者

回复 #19 思一克 的帖子

嗯......

按照我的理解,从代码上看,如果kernel memory space只有一个 pgd 的话,也不会产生 vmalloc()相关的页错的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP