免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
31 [报告]
发表于 2009-05-20 10:14 |只看该作者
我找到了2.6.29内核,和前面的一样的。vmalloc也是fault处理的。



  1. /*
  2. * X86_32
  3. * Handle a fault on the vmalloc or module mapping area
  4. *
  5. * X86_64
  6. * Handle a fault on the vmalloc area
  7. *
  8. * This assumes no large pages in there.
  9. */
  10. static int vmalloc_fault(unsigned long address)
  11. {
  12. #ifdef CONFIG_X86_32
  13.         unsigned long pgd_paddr;
  14.         pmd_t *pmd_k;
  15.         pte_t *pte_k;

  16.         /* Make sure we are in vmalloc area */
  17.         if (!(address >= VMALLOC_START && address < VMALLOC_END))
  18.                 return -1;

  19.         /*
  20.          * Synchronize this task's top level page-table
  21.          * with the 'reference' page table.
  22.          *
  23.          * Do _not_ use "current" here. We might be inside
  24.          * an interrupt in the middle of a task switch..
  25.          */
  26.         pgd_paddr = read_cr3();
  27.         pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
  28.         if (!pmd_k)
  29.                 return -1;
  30.         pte_k = pte_offset_kernel(pmd_k, address);
  31.         if (!pte_present(*pte_k))
  32.                 return -1;
  33.         return 0;
  34. #else
  35.         pgd_t *pgd, *pgd_ref;
  36.         pud_t *pud, *pud_ref;
  37.         pmd_t *pmd, *pmd_ref;
  38.         pte_t *pte, *pte_ref;

  39.         /* Make sure we are in vmalloc area */
  40.         if (!(address >= VMALLOC_START && address < VMALLOC_END))
  41.         .....

复制代码

论坛徽章:
0
32 [报告]
发表于 2009-05-20 10:58 |只看该作者
原帖由 eexplorer 于 2009-5-18 14:47 发表
> 但Solaris的不连续物理内存的分配函数也可以使用,任意不连续物理内存用做DMA时,都通过调用一个单独的DMA
> 函数来分析这片内存区域,看它是由多少个连续物理内存组成的,返回每个连续物理内存的地址。
在linux kernel里,vmalloc应用场景不多,一般是用于kernel access一些firmware, alloc kernel module之类的。设备做dma的memory最后还是都会通过kmalloc, alloc_page来分配。

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



你是唯一真正明白我想说什么的。

我说的Sg list和硬件支持不支持sg没有关系,实际上只需要一个连续物理内存的分析函数就可以了。

给我点时间,我肯定可以为vmalloc做一个,这样vmalloc分配内存的内存就可以为任意设备DMA用了。

当然,既然vmalloc用的很少的话,就没太大意义了。

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

回复 #31 思一克 的帖子

嗯,vmalloc()的代码肯定是有的,因为至少paging level=4的情况很可能会有页错的。

不过,我也有遗漏,我把alloc_vm_area()和alloc_vmap_area()弄混了。

论坛徽章:
0
34 [报告]
发表于 2009-05-20 12:36 |只看该作者
原帖由 raise_sail 于 2009-5-20 11:34 发表
嗯,vmalloc()的代码肯定是有的,因为至少paging level=4的情况很可能会有页错的。

不过,我也有遗漏,我把alloc_vm_area()和alloc_vmap_area()弄混了。


是这样的:就是无论什么分配,如果是允许物理页不连续的,比如vmalloc或用户的malloc,mmap之类的,一定是通过page_fault来实现的。
如果非要不通过page_fault,技术上是可以的,但实现上是笨拙的和浪费的。
所以,无论哪个版本内核,vmalloc都是通过page_fault的(应该是这样,不100%肯定)。

论坛徽章:
0
35 [报告]
发表于 2009-05-20 13:39 |只看该作者
原帖由 思一克 于 2009-5-20 12:36 发表


是这样的:就是无论什么分配,如果是允许物理页不连续的,比如vmalloc或用户的malloc,mmap之类的,一定是通过page_fault来实现的。
如果非要不通过page_fault,技术上是可以的,但实现上是笨拙的和浪费的 ...


vmalloc肯定是通过page fault进行page table同步的。vmalloc先在kernel virtual space找出一段空间,分配出物理页,然后更新到init_mm.pgd所指的page table中。但是当前进程的page table中kernel virtual space那段还是要通过page fault来更新。

kernel并不是只有一个pgd。kernel会借用当前进程的页表,如果当前进程的页表(kernel virtual space部分)没有更新的话,会产生page fault.

论坛徽章:
0
36 [报告]
发表于 2009-05-20 14:11 |只看该作者
原帖由 思一克 于 2009-5-20 12:36 发表

是这样的:就是无论什么分配,如果是允许物理页不连续的,比如vmalloc或用户的malloc,mmap之类的,一定是通过page_fault来实现的。
如果非要不通过page_fault,技术上是可以的,但实现上是笨拙的和浪费的。
所以,无论哪个版本内核,vmalloc都是通过page_fault的(应该是这样,不100%肯定)。
...


这个说法肯定不对。

用不用page fault和这个内存是不是在线内存(wired memory)有关,和连不连续没关系,至少不是问题根源。

Solaris的内核内存很大部分是在线内存(wired memory),都不需要page fault,但Solaris最常用的内核内存分配函数是不保证物理内存连续的。

论坛徽章:
0
37 [报告]
发表于 2009-05-20 15:16 |只看该作者
原帖由 Solaris12 于 2009-5-20 14:11 发表


这个说法肯定不对。

用不用page fault和这个内存是不是在线内存(wired memory)有关,和连不连续没关系,至少不是问题根源。

Solaris的内核内存很大部分是在线内存(wired memory),都不需要page fault ...


我说的是LINUX的不同版本。SOLARIS不懂,更不知道它内核是如何做的。一点研究都没有。

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

回复 #37 思一克 的帖子

vmalloc()页错与否,有两个因素,一个pgd_alloc()时与init_mm共享页表的程度。另一个是,vmalloc()分配的时机,pgd_alloc()之后的vmalloc()出来的内存才有可能发生,但不是一定的。主要看page level有多少。

To Solaris12:

wired memory是什么意思?我知道BSD里也有这个概念,但没弄太明白,就是在页表里已经映射好的?谢谢

论坛徽章:
0
39 [报告]
发表于 2009-05-20 17:53 |只看该作者
原帖由 思一克 于 2009-5-20 15:16 发表


我说的是LINUX的不同版本。SOLARIS不懂,更不知道它内核是如何做的。一点研究都没有。


wired memory不是Solaris独有的概念。所有OS设计都有这种概念,叫法不同罢了。

内核里的wired memory, 占大多数,是不需要page fault的,是non-pagable的,决定是不是wired memory和内存是否连续没多大关系,不是设计上要考虑的因素。

论坛徽章:
0
40 [报告]
发表于 2009-05-21 09:01 |只看该作者
原帖由 Solaris12 于 2009-5-20 17:53 发表


wired memory不是Solaris独有的概念。所有OS设计都有这种概念,叫法不同罢了。

内核里的wired memory, 占大多数,是不需要page fault的,是non-pagable的,决定是不是wired memory和内存是否连续没多大关 ...


你说的就是LINUX里面的固定映射内核地址。不需要page_fault. 因为早已经映射好了。就没有fault了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP