vmalloc

函数调用流程

vmalloc()
    __vmalloc_node()
        __vmalloc_node_range()
            __get_vm_area_node()
            __vmalloc_area_node()
                kmalloc_node()
                vmap_pages_range()

vmalloc() 从 vmalloc 区域申请虚拟内存,并且从 buddy 分配器申请物理内存后,然后 调用 vmap_pages_range() 将物理内存映射到虚拟内存中,此虚拟内存空间不会出现 Page Fault

(x86_64) 如果进程 A 陷入内核空间,通过 vmalloc() 分配内存 memA,如上解释不会出现 Page Fault。 但是进程 B 后面再陷入内核空间,并且也访问内存 memA,这时候内核会发生 Page Fault 来同步内核页表, 而不是发生 Page Fault 来申请物理内存。

零散知识点

  • 为什么 vmalloc() 申请的虚拟内存大小 总是比 申请的物理内存小?

/proc/vmallocinfo 的 第二列 与 倒数第二列,如下:

# cat /proc/vmallocinfo
0x00000000d4d806e4-0x00000000e109dff2   20480 start_kernel+0x478/0x690 pages=4 vmalloc N0=4
0x00000000e109dff2-0x00000000caa5ddd3    8192 gicv2m_init_one+0xa8/0x224 phys=0x0000000008020000 ioremap
0x00000000fa4bd407-0x00000000777a02db   20480 kernel_clone+0x5c/0x3b8 pages=4 vmalloc N0=4
0x00000000777a02db-0x00000000802411ee    8192 bpf_prog_alloc_no_stats+0x3c/0x1b8 pages=1 vmalloc N0=1
0x00000000916f1123-0x000000007c459509 16187392 paging_init+0x130/0x60c phys=0x0000000040210000 vmap

因为由 vmalloc() 申请的虚拟内存默认会添加一页 Guard 页,如下:

mm/vmalloc.c

include/linux/vmalloc.h

Last updated

Was this helpful?