ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

init remove_pte_table

init remove_pte_table remove_pte_table是 x86-64 架构中用于拆除 PTE 层级页表映射的核心函数位于arch/x86/mm/init_64.c。它负责在内存热移除或 vmemmap 回收时将指定虚拟地址范围内的 PTE 条目清除并处理页表页的释放。核心作用逐页清除与条件释放这个函数遍历一个 PTE 页表中的所有条目对每个有效的 PTE 执行清除操作。它的关键设计在于区分 direct mapping内核直接映射和 non-direct mapping如 vmemmap因为两者的页表页释放策略完全不同。核心逻辑解析根据搜索到的补丁和源码函数的核心逻辑如下static void __meminit remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, bool direct) { unsigned long next, pages 0; pte_t *pte; phys_addr_t phys_addr; pte pte_start pte_index(addr); for (; addr end; addr next, pte) { next pte_addr_end(addr, end); if (!pte_present(*pte)) continue; /* 跳过低端物理地址 */ phys_addr pte_val(*pte) (addr PAGE_MASK); if (phys_addr (phys_addr_t)0x40000000) return; if (PAGE_ALIGNED(addr) PAGE_ALIGNED(next)) { /* * Do not free direct mapping pages since they were * freed when offlining, or simply not in use. */ if (!direct) free_pagetable(pte_page(*pte), 0); spin_lock(init_mm.page_table_lock); pte_clear(init_mm, addr, pte); spin_unlock(init_mm.page_table_lock); pages; } /* 后续版本移除了 !PAGE_ALIGNED 分支 */ } flush_tlb_all(); if (direct) update_page_count(PG_LEVEL_4K, -pages); }关键设计细节direct参数的作用这是最核心的区分。direct true内核线性映射不释放PTE 指向的页面。注释明确指出“direct mapping pages 在 offlining 时已被释放或根本不在使用中”。direct mapping 的页面从未被“分配”过它们只是物理内存的直接映射因此无需释放。direct falsevmemmap 等非直接映射调用free_pagetable()释放 PTE 指向的页面。pte_clear的锁保护清除 PTE 条目时持有init_mm.page_table_lock防止并发修改。update_page_count仅在direct true时更新页表统计因为只有 direct mapping 的页面计数才有意义。历史演进根据 2021 年的补丁函数中原本存在的!PAGE_ALIGNED分支被移除。该分支用于处理 vmemmap 中不完整的页面用PAGE_INUSE标记未使用的struct page但后来被简化。这意味着现代内核中remove_pte_table只处理页对齐的完整页面清除。在页表拆除链条中的位置remove_pte_table是页表拆除递归调用链的最底层remove_pagetable → remove_p4d_table → remove_pud_table → remove_pmd_table → remove_pte_table上层函数如remove_pmd_table在调用完remove_pte_table后会继续调用free_pte_table()释放 PTE 页表本身。这种分层设计确保了从顶层 PGD 到底层 PTE 的逐级清理和释放。
返回列表