多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

page_alloc prep_move_freepages_block

page_alloc prep_move_freepages_block prep_move_freepages_block()是伙伴系统中迁移类型转换前的准备工作函数负责计算待移动的 pageblock 范围并统计该范围内的空闲页和可移动页数量为后续的“偷页”决策提供依据。核心作用它本身不执行实际的页块移动而是完成两项关键准备确定可操作的 pageblock 范围根据传入的page计算其所属 pageblock 的起止 PFN并处理跨越 zone 边界的截断问题。统计关键计数计算该范围内有多少空闲页num_free以及其中有多少是可移动页num_movable供steal_suitable_fallback()判断“偷整个 pageblock”是否值得。参数解析参数含义zone目标内存区域page光标页cursor page用于定位所属 pageblockstart_pfn输出调整后的起始页帧号end_pfn输出调整后的结束页帧号包含num_free输出该范围内的空闲页总数num_movable输出其中可移动页的数量核心逻辑1. 计算 pageblock 范围pfn page_to_pfn(page); start pageblock_start_pfn(pfn); end pageblock_end_pfn(pfn) - 1;以page所属的 pageblock 为基准计算出对齐的起止 PFN。2. 处理 zone 边界这是该函数最重要的职责。如果 pageblock 跨越了 zone 边界必须截断到 zone 范围内/* Do not cross zone boundaries */ if (!zone_spans_pfn(zone, start)) start zone-zone_start_pfn; if (!zone_spans_pfn(zone, end)) return false;这里有一个重要的历史修复早期代码在start超出 zone 时只回退到pfn而不是zone-zone_start_pfn。这导致 DMA zone 的第一个 pageblockstart_pfn 1被“偷”时pivot 页之前的大量页被遗留在了旧链表上加剧了碎片化。修复后改为截断到 zone 起始位置保证整个 zone 内的范围都被正确处理。3. 统计空闲页和可移动页遍历调整后的[start, end]范围for (pfn start; pfn end; ) { if (!pfn_valid_within(pfn)) { pfn; continue; } page pfn_to_page(pfn); if (!PageBuddy(page)) { pfn; continue; } order buddy_order(page); (*num_free) 1 order; if (is_migrate_movable(get_pcppage_migratetype(page))) (*num_movable) 1 order; pfn 1 order; }只统计空闲的 Buddy 页PageBuddy。num_free累加空闲页数。num_movable累加可移动的空闲页数MIGRATE_MOVABLE或MIGRATE_CMA。4. 返回结果return true; // 或 falsezone 边界不满足时返回false表示该 pageblock 无法在给定 zone 内完整操作调用方应放弃“偷整个 block”的尝试。调用场景它被steal_suitable_fallback()调用用于判断“偷整个 pageblock”是否值得steal_suitable_fallback() └── prep_move_freepages_block(zone, page, start_pfn, end_pfn, free_pages, movable_pages) ├── 统计该 block 的空闲页/可移动页 └── 根据结果决定是否值得 claim 整个 block如果num_free和num_movable的统计结果显示该 block 大部分是空闲/可移动的内核就会偷取整个 pageblock通过__move_freepages_block()移动所有空闲页并更新 pageblock 的迁移类型标记从而减少碎片。总结prep_move_freepages_block()是“偷页”策略的侦察兵它计算 pageblock 的有效范围处理 zone 边界截断统计该范围内的空闲页和可移动页数量供上层决策是否值得将整个 block 转换为新的迁移类型。它的正确性直接影响反碎片效果——错误的边界截断会导致页块被遗留加剧长期碎片化。
返回列表