You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于内核vmalloc中vmap_area与vm_struct双结构体的疑问

为什么Linux内核用vmap_area和vm_struct两个结构体而非合并?

先贴出相关内核结构体代码:

struct vm_struct {
    struct vm_struct    *next;
    void            *addr;
    unsigned long       size;
    unsigned long       flags;
    struct page     **pages;
#ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC
    unsigned int        page_order;
#endif
    unsigned int        nr_pages;
    phys_addr_t     phys_addr;
    const void      *caller;
};

struct vmap_area {
    unsigned long va_start;
    unsigned long va_end;

    struct rb_node rb_node;         /* address sorted rbtree */
    struct list_head list;          /* address sorted list */

    /*
     * The following two variables can be packed, because
     * a vmap_area object can be either:
     *    1) in "free" tree (root is vmap_area_root)
     *    2) or "busy" tree (root is free_vmap_area_root)
     */
    union {
        unsigned long subtree_max_size; /* in "free" tree */
        struct vm_struct *vm;           /* in "busy" tree */
    };
};

核心原因拆解:

  • 职责分离,降低耦合
    vm_struct专注描述已分配vmap内存块的核心属性:比如对应的物理页数组、内存大小、申请标记、调用者信息等,完全和具体内存资源绑定。而vmap_area只负责虚拟地址空间的管理:记录地址范围、维护红黑树/链表节点实现高效的地址查找、分配、释放,还通过union区分空闲/忙状态。
    拆分后,虚拟地址管理逻辑和内存块资源管理逻辑完全解耦——优化地址分配算法时只需改动vmap_area相关代码,调整内存块属性时也不会影响地址管理,维护成本大幅降低。

  • 优化内存开销,适配两种状态
    vmap_area里的union是关键设计:当它代表空闲虚拟地址块时,仅需subtree_max_size辅助红黑树高效查找;当转为已分配状态时,才关联对应的vm_struct。如果合并结构体,空闲地址块也得带着vm_struct里的pages、nr_pages等无用字段,这对内存紧张的内核来说是没必要的浪费——系统中可能存在大量空闲地址块,轻量的vmap_area能节省不少内存。

  • 历史演进与稳定性优先
    早期内核只有vm_struct管理vmap内存,后来随着虚拟地址空间需求复杂化(比如支持更大地址范围、更高效分配释放),才新增vmap_area专门负责地址管理。强行合并需要修改大量依赖vm_struct的旧代码,不仅工作量极大,还容易引入兼容性问题和bug。内核作为稳定性优先的基础软件,不会轻易做这种破坏性重构,而是选择新增结构扩展功能,保留原有结构的兼容性。

内容的提问来源于stack exchange,提问作者Jianhui Zhao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:25:16