首页 / 资讯中心 / 文章详情

linux kernel struct 之 ptdesc

linux kernel struct 之 ptdesc ★ FEATURED ARTICLE
struct ptdesc的定义在 Linux 内核的include/linux/mm_types.h文件中早期版本曾放在include/linux/pgtable.h。它的设计目标是将页表元数据从struct page中拆分出来目前通过完全覆盖overlaystruct page的内存布局来实现。定义代码根据内核补丁以 v6 版本为例其完整定义如下struct ptdesc { unsigned long __page_flags; union { struct rcu_head pt_rcu_head; struct list_head pt_list; struct { unsigned long _pt_pad_1; pgtable_t pmd_huge_pte; }; }; unsigned long _pt_s390_gaddr; union { struct mm_struct *pt_mm; atomic_t pt_frag_refcount; unsigned long _pt_pad_2; }; #if ALLOC_SPLIT_PTLOCKS spinlock_t *ptl; #else spinlock_t ptl; #endif unsigned int __page_type; atomic_t _refcount; #ifdef CONFIG_MEMCG unsigned long pt_memcg_data; #endif };核心字段说明字段说明__page_flags与page-flags相同页表场景下通常未使用pt_rcu_head用于延迟释放页表页的 RCU 回调与pt_list共用内存pt_list串联已使用的页表用于 s390 和 x86pmd_huge_pte受ptl保护用于透明大页THP场景_pt_s390_gaddr仅 s390 架构使用用于 gmap 地址追踪pt_mm仅 x86 架构使用用于 PGD页全局目录pt_frag_refcount仅 PowerPC 和 s390 使用用于碎片化页表追踪ptl页表锁保护页表操作ALLOC_SPLIT_PTLOCKS控制是指针还是内嵌_refcount引用计数与page-_refcount相同s390 页表使用pt_memcg_data内存 cgroup 数据追踪页表的内存使用关键设计约束定义末尾有一条静态断言这是整个设计的核心约束static_assert(sizeof(struct ptdesc) sizeof(struct page));这意味着ptdesc的大小不能超过struct page因为当前它完全复用struct page的内存空间。同时代码通过TABLE_MATCH宏断言关键字段的偏移量与struct page中对应字段完全一致确保两种类型可以安全地相互转换。在NOMMU配置下struct ptdesc的定义会被移到mm_types.h因为spinlock_t和struct page的定义顺序会影响编译。核心定位struct ptdesc目前完全覆盖overlay在struct page之上也就是说它暂时复用struct page的内存空间但以独立的类型存在。它的长期目标是让页表可以独立于struct page进行动态分配从而进一步精简struct page结构。与pgtable_t的关系在大多数架构上pgtable_t原本就是struct page *的 typedef。struct ptdesc的引入是为了逐步用struct ptdesc *替代pgtable_t使页表描述符的类型更加明确。不过这一转换面临架构差异的挑战在 s390、PowerPC、sparc 和 m68k除 SUN3上pgtable_t被定义为pte_t *因为每个页表可能小于一个PAGE_SIZE无法直接映射到单个struct page。因此struct ptdesc的推广需要各架构的配合。在内存管理中的角色struct ptdesc是页表操作分配、释放、遍历的核心载体。在___pmd_free_tlb中virt_to_ptdesc(pmd)就是将页表页的虚拟地址转换为struct ptdesc指针然后通过tlb_remove_ptdesc加入延迟释放队列。这种设计使得页表的生命周期管理可以与struct page解耦为未来更灵活的页表内存管理铺平道路。
阅读完成 · 觉得有帮助?
咨询建站