alloc_pages_exact_noprof()是alloc_pages_exact()的无 profiling 底层实现核心目标是分配“恰好满足需求”的物理连续内存而非伙伴系统默认的 2 的幂次页块。设计动机消除高阶分配的浪费伙伴系统只能按2^order个页分配。如果你需要 5MBget_order(5MB)会算出 order118MB于是分配了 8MB浪费了 3MB 的物理连续内存。对于视频驱动等需要大块连续缓冲的场景这种浪费不可接受。核心实现void *alloc_pages_exact_noprof(size_t size, gfp_t gfp_mask) { unsigned int order get_order(size); unsigned long addr; if (WARN_ON_ONCE(gfp_mask __GFP_COMP)) gfp_mask ~__GFP_COMP; addr __get_free_pages(gfp_mask, order); return make_alloc_exact(addr, order, size); } EXPORT_SYMBOL(alloc_pages_exact_noprof);关键步骤get_order(size)计算满足size的最小阶数。例如 5MB 会算出 order118MB。强制清除__GFP_COMP如果调用方传入__GFP_COMP会触发警告并清除它。因为make_alloc_exact()内部要调用split_page()而split_page()不能用于复合页VM_BUG_ON_PAGE(PageCompound(page))。__get_free_pages()按计算出的阶数分配页块返回虚拟地址。make_alloc_exact()核心“裁剪”逻辑——把多余页释放掉前面已详细讲过。与alloc_pages_exact()的关系现代内核中alloc_pages_exact()是一个宏最终展开为alloc_pages_exact_noprof()。_noprof后缀表示不带内存分配 profiling 钩子的版本供不需要 profiling 的调用方使用避免不必要的开销。关键约束必须用free_pages_exact()释放因为split_page()已把页块拆成独立单页不能再作为整体释放。受MAX_ORDER限制不能分配超过伙伴系统最大阶数的内存。size参数必须一致释放时传入的size必须和分配时相同否则释放范围会错。总结alloc_pages_exact_noprof()通过“先按 2 的幂次分配再用split_page()拆分并释放多余页”的策略实现“恰好满足需求”的物理连续内存分配。它解决了伙伴系统只能按 2 的幂次分配导致的内存浪费问题代价是必须用配套的free_pages_exact()逐页释放且不能用于复合页。