目录
初识 VMALLOC 映射区
VMALLOC 映射区原理
VMALLOC 映射区源码分析
VMALLOC 映射区使用场景
VMALLOC 映射区原理
在 Linux 内核空间存在一个特殊区域,该区域的内存虚拟内存部分是连续的,而物理内存部分则是离散的,内核称这个区域为 VMALLOC 映射区,内核提供 VMALLOC 分配器用于从该区域分配内存. 之前研究过线性映射区,该区域的内存特点是虚拟内存是连续的,映射的物理内存也是连续的,但 Linux 使用 Buddy 分配器从该区域分配物理内存,然后通过线性映射关系可以获得对应的虚拟内存,又因为 Buddy 分配的内促必须是 2 的指数个页表,最大支持分配 4MiB 的物理内存。但内核在有的场景需要大块内存,并且不在意物理内存是否连续,那么这是会采用 VMALLOC 映射区的内存,其可以提供超级大块的内存需求.
Linux 会将内核虚拟地址空间规划成不同的区域(上图是 X86 4-level 页表内核空间布局),其中将 [VMALLOC_START, VMALLOC_END) 区域设置为VMALLOC 映射区,其长度与实际的架构有关,但无论何种架构都可以通过宏 VMALLOC_START 和 VMALLOC_END 确认 VMALLOC 映射区的。VMALLOC 映射区与周围相邻的区域都存在 HOLE,以防止 VMALLOC 越界. VMALLOC 分配器在 Linux 里的主要用途如下:
- 大块连续虚拟内存: VMALLOC 映射区能够提供大块的连续虚拟内存空间,用于满足需要大块内存但物理内存不需要连续的场景
- 非连续物理内存映射: 通过 VMALLOC 映射区,内核可以将非连续的物理内存页映射到连续的虚拟地址空间,从而方便内核访问这些内存页
- 特定需求的内存映射: VMALLOC 映射区常用于满足一些特定的内存映射需求,例如驱动程序映射硬件设备的内存等
VMALLOC 内存构建
VMALLOC 映射区的内存通过 VMALLOC 分配器进行分配,其需要从 VMALLOC 映射区分配连续的虚拟内存,然后再从 Buddy 里分配离散的物理内存,最后在建立页表映射. VMALLOC 映射区虚拟内存维护在红黑树里,VMALLOC 分配器可以在红黑树里找到一块适合的可用虚拟区域,另外对于物理内存可以是零散的 4KiB 物理页,也可以是 2MiB 物理页,因此最后建立页表时按调用者的需求建立页表.