资讯详情

page_alloc __rmqueue_claim

📅 2026/10/12 2:24:18 | 华诺云谱 👁 阅读
page_alloc __rmqueue_claim
__rmqueue_claim()是伙伴系统 fallback 路径中负责“认领整个 pageblock”的分配函数与负责“只偷单个页块”的__rmqueue_steal()相对。核心职责当请求的迁移类型在常规空闲链表中耗尽时__rmqueue_claim()会从最大阶数向下扫描尝试找到一块可用的 fallback 迁移类型的空闲页块并通过try_to_claim_block()判断是否值得将整个 pageblock 收编为请求类型——这样做可以避免未来反复 fallback减少碎片化。核心逻辑static __always_inline struct page * __rmqueue_claim(struct zone *zone, int order, int start_migratetype, unsigned int alloc_flags) { struct free_area *area; int current_order; int min_order order; struct page *page; int fallback_mt; /* * Do not steal pages from freelists belonging to other pageblocks * i.e. orders pageblock_order. */ if (order pageblock_order alloc_flags ALLOC_NOFRAGMENT) min_order pageblock_order; /* * Find the largest available free page in the other list. */ for (current_order MAX_PAGE_ORDER; current_order min_order; --current_order) { area (zone-free_area[current_order]); /* Advanced into orders too low to claim, abort */ if (!should_try_claim_block(order, start_migratetype)) break; fallback_mt find_fallback_migratetype(area, current_order, start_migratetype); /* No block in that order */ if (fallback_mt -1) continue; page get_page_from_free_area(area, fallback_mt); page try_to_claim_block(zone, page, current_order, order, start_migratetype, fallback_mt, alloc_flags); if (page) { trace_mm_page_alloc_extfrag(page, order, current_order, start_migratetype, fallback_mt); return page; } } return NULL; }关键点解析1. 从最大阶数向下扫描for (current_order MAX_PAGE_ORDER; current_order min_order; --current_order)与__rmqueue_steal()从请求阶数向上找不同__rmqueue_claim()从最高阶开始向下优先尝试最大的空闲块。这是因为认领整个 block 的收益与块大小相关——大块被收编后未来能服务更多高阶分配。2.ALLOC_NOFRAGMENT与min_orderif (order pageblock_order alloc_flags ALLOC_NOFRAGMENT) min_order pageblock_order;当调用方设置了ALLOC_NOFRAGMENT且请求阶数小于pageblock_order时不允许从小于 pageblock 的 order 偷页。因为这样做会把一个 pageblock 拆碎造成不可逆的碎片化。此时min_order被提升到pageblock_order强制只认领完整的大块。3.should_try_claim_block()的提前终止2025 年的重构将should_try_claim_block()从find_suitable_fallback()内部移出放入循环开始处。一旦该函数返回false表示当前 order 迁移类型组合不值得认领直接break跳出循环——因为继续向更低阶扫描只会更不值得认领。这消除了旧代码中依赖find_suitable_fallback()返回魔法值-2的隐式逻辑。4. 与find_suitable_fallback()的协作在重构前的经典实现中__rmqueue_claim()调用find_suitable_fallback(area, current_order, start_migratetype, true)后者返回-2时表示“不可认领”调用方据此break。重构后find_suitable_fallback()被拆分为should_try_claim_block()和find_fallback_migratetype()__rmqueue_claim()直接调用前者来判断是否终止。在分配路径中的位置__rmqueue_claim()是__rmqueue()模式切换链中的关键一环__rmqueue() ├── __rmqueue_smallest() // 同类型最优先 ├── __rmqueue_cma_fallback() // CMA仅 MOVABLE ├── __rmqueue_claim() // 认领整个 block本函数 └── __rmqueue_steal() // 偷单个页最后手段__rmqueue()通过enum rmqueue_mode在多次rmqueue_bulk()调用间记住上次成功的模式避免每次从RMQUEUE_NORMAL重新开始扫描。当__rmqueue_claim()成功时模式重置为RMQUEUE_NORMAL因为请求类型的空闲链表已被“补充”。总结__rmqueue_claim()是 fallback 路径中最“温和”的降级策略它从最大空闲块开始向下扫描在should_try_claim_block()允许的范围内尝试将整个 pageblock 收编为请求类型而不是仅仅偷走一个页块。这种“认领”策略以短期成本可能暂时闲置部分空间换取长期收益减少碎片化、降低未来 fallback 频率是伙伴系统反碎片机制的核心执行者。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑