news 2026/10/10 6:15:46

page_alloc fallbacks[][]

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
page_alloc fallbacks[][]

伙伴系统中迁移类型降级(fallback)的优先级表。当某种迁移类型的空闲链表耗尽时,分配器按这个表尝试从其他类型"偷"页。


一、背景:为什么需要 fallback?

迁移类型与反碎片

  • 空闲页按迁移类型分组(MIGRATE_UNMOVABLE/MOVABLE/RECLAIMABLE等)。

  • 分配时优先从同类型链表取页,保持同类页聚集,减少碎片。

  • __rmqueue_smallest()负责同类型分配。

问题:同类型耗尽怎么办?

  • 如果请求MIGRATE_UNMOVABLE,但MIGRATE_UNMOVABLE链表空了,不能直接失败——那会导致分配失败、系统不可用。

  • 必须允许从其他迁移类型借用页块。

  • 但借用会破坏反碎片:把可移动页块借给不可移动用途,混合后难以整块迁移/回收。

解决:有策略的 fallback

  • 不随便借,而是按预定义的优先级尝试。

  • 优先借"影响最小"的类型。

  • 这就是fallbacks[][]数组的作用。


二、数组定义解析

static int fallbacks[MIGRATE_PCPTYPES][MIGRATE_PCPTYPES - 1] = { [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE }, [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE }, [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE }, };

1. 维度

[MIGRATE_PCPTYPES][MIGRATE_PCPTYPES - 1]
  • 第一维:请求的迁移类型(MIGRATE_PCPTYPES种,即参与 PCP/分组的前几种)。

  • 第二维:候选的 fallback 类型列表,长度为MIGRATE_PCPTYPES - 1(排除自己)。

  • 用指定初始化器[MIGRATE_UNMOVABLE] = {...},清晰对应每种类型。

2. 注释

/* * This array describes the order lists are fallen back to when * the free lists for the desirable migrate type are depleted * * The other migratetypes do not have fallbacks. */
  • "the order lists are fallen back to":当目标类型链表耗尽时,按此顺序尝试其他类型。

  • "The other migratetypes do not have fallbacks":CMA、ISOLATE等不参与 fallback:

    • MIGRATE_CMA:CMA 区域有特殊用途,不能被普通分配随意借用(但可反向:普通类型可借 CMA?实际有特殊处理);

    • MIGRATE_ISOLATE:隔离区,绝对不能借用。

  • 所以数组第一维只覆盖MIGRATE_PCPTYPES。

3. 三行内容

请求类型第一优先 fallback第二优先 fallback
MIGRATE_UNMOVABLEMIGRATE_RECLAIMABLEMIGRATE_MOVABLE
MIGRATE_MOVABLEMIGRATE_RECLAIMABLEMIGRATE_UNMOVABLE
MIGRATE_RECLAIMABLEMIGRATE_UNMOVABLEMIGRATE_MOVABLE

三、优先级的设计逻辑

核心原则:借"影响最小"的类型

不同迁移类型的"可移动性"不同:

  • MIGRATE_MOVABLE:可移动(用户态页),最灵活,可迁移/回收。

  • MIGRATE_RECLAIMABLE:可回收(slab 缓存),可回收但不可迁移。

  • MIGRATE_UNMOVABLE:不可移动(内核结构),既不可迁移也不可回收,最"死"。

破坏顺序(从轻到重):

  1. 借RECLAIMABLE:最坏情况是回收,页块仍可能恢复;

  2. 借MOVABLE:可迁移,但可能造成碎片;

  3. 借UNMOVABLE:最糟糕,永久占据,破坏连续性。

逐行分析

MIGRATE_UNMOVABLE的 fallback

[MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE },
  • 请求不可移动页,但不可移动链表空了。

  • 优先借RECLAIMABLE:可回收,未来能还回来;

  • 再借MOVABLE:可迁移,影响次之;

  • 最后才考虑(虽然表里只列了两个,实际逻辑可能还有更多处理)。

  • 不会借UNMOVABLE(自己),因为已经空了。

MIGRATE_MOVABLE的 fallback

[MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE },
  • 请求可移动页,但可移动链表空了。

  • 优先借RECLAIMABLE:可回收;

  • 再借UNMOVABLE:不可移动,但至少能用;

  • 顺序反映:宁可借不可移动,也不……(这里没有更多选项)。

MIGRATE_RECLAIMABLE的 fallback

[MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE },
  • 请求可回收页,但可回收链表空了。

  • 优先借UNMOVABLE:不可移动但稳定;

  • 再借MOVABLE:可移动;

  • 为什么优先UNMOVABLE?因为 RECLAIMABLE 本身不可迁移,借UNMOVABLE语义更接近(都不可迁移),借MOVABLE反而可能把可移动页块"污染"成不可回收用途。

设计哲学总结

  • 尽量借"能还回来"的类型:RECLAIMABLE优先(可回收);

  • 其次借"影响小"的类型;

  • 避免借"不可逆"的类型,除非别无选择。


四、在 fallback 路径中的使用

__rmqueue_fallback()

static inline struct page *__rmqueue_fallback(struct zone *zone, int order, int start_migratetype, unsigned int alloc_flags) { int current_order, i; struct page *page; struct free_area *area; int migratetype; int fallback_mt; /* * 从最高阶往下找,找能拆出 order 的块 */ for (current_order = MAX_ORDER - 1; current_order >= order; --current_order) { area = &zone->free_area[current_order]; /* * 按 fallbacks 数组顺序尝试其他迁移类型 */ for (i = 0; i < MIGRATE_PCPTYPES - 1; i++) { fallback_mt = fallbacks[start_migratetype][i]; /* 跳过被隔离的类型 */ if (is_migrate_isolate(fallback_mt)) continue; /* 尝试从该类型取页 */ page = get_page_from_free_area(area, fallback_mt); if (!page) continue; /* 找到,取走并拆分 */ del_page_from_free_list(page, zone, current_order, fallback_mt); ... /* * 把该 pageblock 的迁移类型改为请求类型, * 或做其他反碎片处理 */ ... return page; } } return NULL; }

关键点

  1. 按fallbacks[start_migratetype]顺序尝试:

    • i = 0:第一优先 fallback;

    • i = 1:第二优先;

    • 依次尝试。

  2. 跳过隔离类型:

    • is_migrate_isolate(fallback_mt)检查,隔离区不能借。

  3. 借用后可能改变迁移类型:

    • 把借来的 pageblock 标记为请求类型,反映实际用途;

    • 或做其他"反碎片"处理(如判断是否值得偷整个 pageblock)。

  4. 从高阶往下找:

    • 优先用高阶块(可以拆分成多个小块,更灵活);

    • 避免把小块的连续性破坏。


五、与前面内容的呼应

前面出现过的这里的关联
migratetype_names[]MIGRATE_*的名字表
__rmqueue_smallest()同类型分配;失败后走 fallback
__rmqueue_fallback()使用fallbacks[][]表
MIGRATE_PCPTYPES数组第一维大小
is_migrate_isolate()跳过隔离类型
MIGRATE_CMA/MIGRATE_ISOLATE不参与 fallback
set_pageblock_migratetype()借用后可能更新类型
反碎片fallback 策略的核心目标

调用链:

__rmqueue() ├── __rmqueue_smallest() // 同类型 └── if (!page) __rmqueue_fallback() // 跨类型 └── for (i = 0; i < MIGRATE_PCPTYPES - 1; i++) fallback_mt = fallbacks[start_migratetype][i] ...

六、小结表

项说明
数组名fallbacks
维度[MIGRATE_PCPTYPES][MIGRATE_PCPTYPES - 1]
作用定义各迁移类型的降级借用优先级
第一维请求的迁移类型
第二维候选 fallback 类型,按优先级排列
不参与的类型CMA、ISOLATE("The other migratetypes do not have fallbacks")
设计原则优先借"可回收/影响小"的类型
使用点__rmqueue_fallback()
可见性static,文件内私有

三行速查

请求类型优先借其次借
UNMOVABLERECLAIMABLEMOVABLE
MOVABLERECLAIMABLEUNMOVABLE
RECLAIMABLEUNMOVABLEMOVABLE

一句话总结

fallbacks[][]定义了伙伴系统中迁移类型的降级借用优先级:当请求类型的空闲链表耗尽时,按此表依次尝试从其他类型"偷"页;它只覆盖MIGRATE_PCPTYPES三种类型(CMA/ISOLATE不参与),设计原则是优先借"可回收、影响小"的类型(如RECLAIMABLE),以尽量减少对反碎片的破坏。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 6:14:37

从目的到落地:motion-design-skill四级决策框架完整教程

从目的到落地&#xff1a;motion-design-skill四级决策框架完整教程 【免费下载链接】motion-design-skill Universal motion design principles for AI agents — timing, easing, choreography, and Disney animation principles adapted for UI 项目地址: https://gitcode…

作者头像 李华
网站建设 2026/10/10 6:11:35

从OpenGL到现代图形API:渲染思维与架构迁移实战

1. 为什么“会写OpenGL”不等于“懂现代渲染”很多做了五六年OpenGL的朋友&#xff0c;第一次接触现代图形API时都会有一种强烈的挫败感&#xff1a;明明以前几十行就能画出一个三角形&#xff0c;现在光是初始化就要写几百行&#xff1b;以前改一个状态直接调函数就行&#xf…

作者头像 李华
网站建设 2026/10/10 6:11:33

同样是 AI 成片,知漫剧为什么能做到角色画风不跑偏?

绝大多数 AI 漫剧创作者都会遇到同一个棘手难题&#xff1a;批量制作连载剧集时&#xff0c;人物五官、造型、画面画风不断变化&#xff0c;单集单独看尚可&#xff0c;连续播放就会出现明显割裂&#xff0c;大量时间浪费在反复修改画面上。知漫剧&#xff08;zz.jiaxunai.cn&a…

作者头像 李华
网站建设 2026/10/10 6:10:15

用C# WinForms自制轻量定时提醒小工具:快捷时间选择与批量状态管理

每天要处理的琐事太多太碎&#xff0c;系统闹钟、日历提醒和任务管理软件各有各的别扭。我直接用 C# 写了一款轻量定时工具&#xff0c;把快捷时间选择、计划备注和状态批量管理塞进一个不到几百 KB 的单文件里&#xff0c;平时就常驻系统托盘&#xff0c;到点弹窗&#xff0c;…

作者头像 李华
网站建设 2026/10/10 6:09:23

第五篇:Keepalived + LVS 四层负载均衡高可用实战:DR 模式全流程

开篇Keepalived 不只是"VIP 漂移工具"——它天生就是为 LVS&#xff08;Linux Virtual Server&#xff09;设计的。很多人不知道&#xff0c;Keepalived 的看家本领就是管理 LVS 集群&#xff0c;实现四层负载均衡 高可用的一体化方案。本文作为 Keepalived 系列第 …

作者头像 李华
网站建设 2026/10/10 6:07:00

web.py 快速入门:8 行代码构建你的第一个 Python Web 应用

后端Web框架 【免费下载链接】webpy web.py is a web framework for python that is as simple as it is powerful. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/we/webpy 点击查看 免费下载 web.py 是一个"简单而强大"的 Python Web 框架&#xff0c;其…

作者头像 李华