☰
page_alloc __rmqueue
2026/10/12 2:24:15 网站建设 项目流程

__rmqueue()是伙伴系统分配路径的核心调度器。它在持有zone->lock的前提下,按照碎片化风险从低到高的顺序,依次尝试不同的分配策略,直到成功或彻底失败。

核心作用与策略链

它的本质是一个多级降级策略链:先尝试最“干净”的方式(同类型分配),失败后才逐步退而求其次,最终退到“偷页”这种会加剧碎片化的方式。

根据内核代码,典型的策略顺序是:

  1. __rmqueue_smallest():首选策略。在请求的迁移类型空闲链表中,从请求阶数向上查找最小的可用块。

  2. __rmqueue_cma_fallback():仅当请求MIGRATE_MOVABLE且首选失败时尝试。从CMA 区域分配,但不进行破坏性拆分。

  3. __rmqueue_claim():在其他迁移类型中,从最大阶数向下扫描,尝试“认领”整个 pageblock(即把大块的所有权转移给请求类型)。

  4. __rmqueue_steal():最后手段。不关心认领,从请求阶数向上扫描,偷取任何可用的单个页块,会加剧碎片化。

mode参数的优化

参数enum rmqueue_mode *mode是性能优化的关键。在rmqueue_bulk()中,函数会批量分配多个页。如果每次分配都从RMQUEUE_NORMAL(首选策略)开始扫描,在内存碎片化时开销很大。

mode让调用方记住上次成功的策略:如果上次是通过__rmqueue_claim()成功的,这次就直接从该策略开始尝试,跳过高阶扫描。当某个策略成功且“补充”了请求类型的空闲链表后,mode会被重置为RMQUEUE_NORMAL,因为首选策略可能又变得可用了。

在分配路径中的位置

它是rmqueue()和rmqueue_bulk()在持锁状态下调用的核心函数:

rmqueue() / rmqueue_bulk() └── spin_lock(&zone->lock) └── __rmqueue(zone, order, migratetype, alloc_flags, &mode) // ← 这里 ├── __rmqueue_smallest() ├── __rmqueue_cma_fallback() ├── __rmqueue_claim() └── __rmqueue_steal()

总结

__rmqueue()是伙伴系统在持锁状态下的多级分配调度器:它按碎片化风险递增的顺序,依次尝试同类型分配、CMA、认领整块、偷页四种策略。mode参数让批量分配能记忆并复用上次成功的策略,避免重复无效扫描;当策略成功补充了首选类型链表后,模式重置,回归最优路径。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询