资讯动态

page_alloc unreserve_highatomic_pageblock

发布时间:2026/10/13 19:29:52 来源:尧图企业网站定制
unreserve_highatomic_pageblock()是reserve_highatomic_pageblock()的逆操作用于在内存分配即将失败甚至面临 OOM时释放之前保留的 MIGRATE_HIGHATOMIC pageblock将其归还给常规分配使用。核心作用与背景reserve_highatomic_pageblock()它在高阶原子分配失败时从普通页块中“征用”一块作为MIGRATE_HIGHATOMIC保留区。unreserve_highatomic_pageblock()则是在内存压力极大时把这些保留的“救命粮”拿出来救急。它的设计意图是失败的原子分配比 OOM 更容易恢复所以宁可暂时牺牲高阶原子分配的可靠性也要避免 OOM。参数解析参数含义ac分配上下文包含 zonelist、highest_zoneidx、nodemask、migratetype 等force是否强制解除保留即使保留量低于一个 pageblock核心逻辑根据内核源码它的流程如下1. 遍历 zonelist 中的每个 zonefor_each_zone_zonelist_nodemask(zone, z, zonelist, ac-highest_zoneidx, ac-nodemask) {2. 保留量检查除非forceif (!force zone-nr_reserved_highatomic pageblock_nr_pages) continue;非强制模式下如果该 zone 的保留量不超过一个 pageblock保留它不解除。这是“保底”策略至少给高阶原子分配留一点余地。3. 持锁扫描所有 orderspin_lock_irqsave(zone-lock, flags); for (order 0; order MAX_ORDER; order) { struct free_area *area (zone-free_area[order]); page get_page_from_free_area(area, MIGRATE_HIGHATOMIC); if (!page) continue;从低阶到高阶扫描MIGRATE_HIGHATOMIC链表找到第一个有空闲页的 order。4. 更新保留计数处理竞态if (is_migrate_highatomic_page(page)) { zone-nr_reserved_highatomic - min(pageblock_nr_pages, zone-nr_reserved_highatomic); }注释解释了竞态来源在页释放路径中迁移类型的改变是竞态的可能导致同一个 pageblock 的页被多次计入MIGRATE_HIGHATOMIC链表。这里用is_migrate_highatomic_page()判断确保只减一次nr_reserved_highatomic。使用min()防止下溢。5. 转换迁移类型并移动页块set_pageblock_migratetype(page, ac-migratetype); ret move_freepages_block(zone, page, ac-migratetype, NULL); if (ret) { spin_unlock_irqrestore(zone-lock, flags); return ret; }把该 pageblock 的迁移类型改为请求类型ac-migratetype而不是MIGRATE_UNMOVABLE或其他。注释解释了原因如果总是转成UNMOVABLE会增加“无法完全释放的 pageblock”数量加剧碎片化。move_freepages_block()将该 pageblock 内的空闲页移到新类型的链表。成功移动页数 0则返回表示解除成功。历史演进2016 年 Minchan Kim 的修复旧代码只要找到MIGRATE_HIGHATOMIC的 pageblock 就bail out即使没有真正移动任何页。修复后只有move_freepages_block()实际移动了页ret 0才返回成功。同时增加了is_migrate_highatomic_page()检查避免竞态导致的重复计数。2026 年的锁守卫重构用guard(spinlock_irqsave)(zone-lock)替代显式的spin_lock_irqsave/spin_unlock_irqrestore简化代码并避免遗漏解锁。调用场景它被__alloc_pages_slowpath()在内存分配即将失败、准备触发 OOM 之前调用作为最后的挽救手段__alloc_pages_slowpath() └── if (gfp_mask __GFP_DIRECT_RECLAIM) └── unreserve_highatomic_pageblock(ac, false) // 先尝试非强制 └── if (仍然失败) unreserve_highatomic_pageblock(ac, true) // 强制解除 └── retry reclaim once more总结unreserve_highatomic_pageblock()是内存分配器的紧急储备释放机制它在分配即将失败时遍历 zonelist 中的 zone将MIGRATE_HIGHATOMIC保留的 pageblock 转为请求类型并移走空闲页以换取分配成功、避免 OOM。它通过force参数控制是否保留最后一个 pageblock通过is_migrate_highatomic_page()处理竞态计数并选择转换为ac-migratetype而非UNMOVABLE以最小化碎片化。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑