page_alloc free_pages_exact

发布时间:2026/10/14 6:29:19
page_alloc free_pages_exact
free_pages_exact()是alloc_pages_exact()的配套释放函数用于释放由后者分配的“精确大小”物理连续内存。核心实现void free_pages_exact(void *virt, size_t size) { unsigned long addr (unsigned long)virt; unsigned long end addr PAGE_ALIGN(size); while (addr end) { free_page(addr); addr PAGE_SIZE; } } EXPORT_SYMBOL(free_pages_exact);为什么不能直接用free_pages()这是理解该函数的关键。alloc_pages_exact()内部做了两件事按高阶分配用__get_free_pages(gfp, order)分配了一个2^order页的大块。裁剪多余部分调用make_alloc_exact()其中split_page()把这个非复合高阶页拆成了2^order个独立的单页然后逐页释放了不需要的尾部页。关键后果经过split_page()后这个页块在伙伴系统看来不再是一个整体而是2^order个独立的 order-0 页。如果调用free_pages(virt, order)它会尝试把整个块作为一个高阶页释放但页块已经被拆散元数据不一致会导致伙伴系统损坏。必须逐页释放每页作为独立的 order-0 页归还。逐页释放的逻辑unsigned long end addr PAGE_ALIGN(size); while (addr end) { free_page(addr); addr PAGE_SIZE; }PAGE_ALIGN(size)向上取整到页边界。因为分配时make_alloc_exact()也是按PAGE_ALIGN(size)计算保留范围的释放必须用相同的对齐方式否则会释放错误数量的页。free_page(addr)释放单个页等价于free_pages(addr, 0)。循环直到覆盖[virt, virt PAGE_ALIGN(size))的全部页。与分配函数的严格配对分配函数配套释放函数原因alloc_pages_exact()free_pages_exact()页块被split_page()拆分必须逐页释放alloc_pages_exact_nid()free_pages_exact()同上__get_free_pages()free_pages()页块保持完整可整体释放alloc_pages()__free_pages()同上size必须与分配时一致如果分配时传size 5000PAGE_ALIGN后 8192释放时传size 4096那么只会释放第 1 页剩下的页永久泄漏。总结free_pages_exact()是alloc_pages_exact()的严格配对释放函数它逐页释放[virt, virt PAGE_ALIGN(size))范围内的内存。之所以不能像free_pages()那样整体释放是因为alloc_pages_exact()内部的split_page()已经把页块拆成了独立单页。调用时必须传入与分配时相同的size否则会造成内存泄漏或错误释放。