vmalloc 与内核虚拟连续映射
这页讲的是:有些内核数据结构希望自己看到的是一大片连续地址,但底层物理页未必真能连续拿出来。学这页的重点,是理解 vmalloc 解决的是“虚拟地址连续”,不是“物理地址连续”,它是在地址映射层给内核腾出更灵活的组织空间。
这块是什么
vmalloc 与内核虚拟连续映射,讲的是 Linux 如何把多页物理上不连续的内存,通过页表映射成一段对内核来说连续可用的虚拟地址区域。它关注的是“内核自己用起来是不是一整段顺手地址”,而不是去硬凑一大片连续物理内存。
可以把它理解成:仓库里的货物可能散落在不同库位,但你可以在总控台上给它们编成一条连续货架编号。对管理者来说,这条编号是连着的;至于后面真实货位是不是挨着,并不重要。
它负责什么
提供虚拟连续区域
- 让内核代码能把一片较大区域当连续地址来使用
- 不要求底层物理页真的连成一大块
- 缓解高阶物理连续分配的压力
- 把地址便利性和物理现实拆开处理
承接较大但不必物理连续的需求
- 适合一些规模较大、寿命较长的数据结构
- 比直接硬要大块连续物理页更现实
- 让某些大区域分配不必过度依赖伙伴系统高阶块
- 给内核提供另一条大块组织路径
在页表层做组织
- 通过映射把散页拼成连续虚拟视图
- 强调地址空间管理而不只是页库存
- 让内核能利用虚拟地址这层抽象来避开部分碎片压力
- 把“连续”从物理问题转成映射问题
为什么它不是“更高级的大块分配”
| 如果想得太简单 | 会怎样 | 真正关键在哪 |
|---|
| 觉得 vmalloc 只是更好用的大内存接口 | 会忽略它和 kmalloc / buddy allocator 的连续性语义完全不同。 | 它给的是虚拟连续,不是物理连续。 |
| 把它当 DMA 缓冲来源 | 容易在需要设备物理可达性的地方走错路。 | 很多设备路径关心的仍是物理连续或可映射规则,而不是虚拟顺手。 |
| 只看能不能拿到大区域 | 会漏掉额外页表开销、地址转换成本和访问特性差异。 | 它用灵活性换来额外映射管理成本。 |
| 觉得它能替代所有页级分配 | 会混淆地址组织问题和物理页供应问题。 | 底层物理页还是要先存在,只是无需挨在一起。 |
关键概念
| 概念 | 现在怎么理解 |
|---|
| vmalloc | 把物理散页映射成内核虚拟连续地址区的一类分配方式。 |
| 虚拟连续 | 从内核代码视角看,地址是一整段连续的。 |
| 物理不连续 | 底层真正承载这段区域的页,不要求彼此挨着。 |
| 页表映射 | 把多张散页组织成连续虚拟视图的关键机制。 |
| 地址便利性 | 某些场景真正想要的是“好用的一整段地址”,不一定非要硬件眼里的连续物理块。 |
为什么重要
- 它解释了为什么“大一点的内核内存需求”并不总是意味着去赌高阶连续页成功率。
- 很多内核结构真正关心的是地址空间好组织,而不是设备侧物理连续。
- 理解这层后,你会更容易把 buddy allocator、页表映射、DMA/CMA 和内核地址空间组织区别开。
- 它让你看到:内核也在充分利用虚拟地址抽象,不是所有问题都直接压给物理内存连续性。
常见误解
- 误解一:vmalloc 比 kmalloc 更高级,所以大块都该优先用它。实际上它适配的问题类型不同。
- 误解二:看起来连续就代表物理也连续。实际上两者正是 vmalloc 刻意拆开的。
- 误解三:只要不需要设备访问,连续性就完全不重要。实际上虚拟连续本身也是一种很重要的可编程性需求。
它不负责什么
- 它不保证设备能直接拿这片区域去做 DMA;那常常要看更严格的设备可达性与连续性要求。
- 它不创造物理页,只是在已有物理页之上做映射组织。
- 它不替代伙伴系统;底层散页还是要由页级分配体系提供。
和其他模块的关系
| 相关模块 | 关系 |
|---|
| buddy allocator | vmalloc 仍要先拿到若干底层页,只是不用这些页彼此物理相邻。 |
| 页表与地址空间 | 它的核心价值正是借助页表把散页拼成连续虚拟区域。 |
| DMA / CMA | 这两类更强调设备侧约束和物理连续性,恰好能帮助你看清 vmalloc 的边界。 |
| 大内核数据结构 | 某些仅供 CPU 使用、追求地址便利的大对象区域更容易长成 vmalloc 问题。 |
读完这页后,你应该能回答
- 为什么 vmalloc 真正解决的是“虚拟地址连续”,而不是“物理页必须连续”?
- 为什么它能缓解部分高阶连续页压力,却又不能替代 DMA/CMA 这类需求?
- 为什么 buddy allocator、vmalloc 和页表映射应该作为同一张图里的不同层次来看?
后面适合继续问:什么时候一个需求更像 vmalloc 问题,而不是 kmalloc 或 DMA 问题?为什么“CPU 看着连续”和“设备能顺手访问”是两回事?如果系统虚拟地址空间本身紧张,会怎样反过来影响 vmalloc?