① 本地节点
只 compact
不 reclaim
② 跨节点
madvised / 同步
reclaim + compact
③ 基础页
任意节点
THP 失败时
第一步的承诺:本地大页缺页低延迟
只做本地 compaction;不回收,也不去别的节点拿
alloc_pages_mpol() 第一遍
gfp | __GFP_THISNODE | __GFP_NORETRY
order == HPAGE_PMD_ORDER;非 interleave
当前/首选 node 允许;THISNODE 不回退
第二、三步不变
第二步:madvised / 同步 compaction
第三步:THP 失败 → 基础页
缺口只在第一步
本地 THP 缺页
node 0
fast path 失败
freelist 没有连续页
direct compaction
只压缩
分出页?
失败则看下一步
compaction 只搬移本地页
把可移动页挪开,拼出连续块
不 evict、不写回、不跨节点
但 compaction 结果不止一种
deferred / skipped
performed but failed
旧代码只挡住 deferred / skipped
实际执行却失败 → 仍会进入 reclaim
2f0799a0ffc0
恢复 node-local THP
b39d0ee2632d
deferred / skipped 不 reclaim
cc638f329ef6
只 compact + NORETRY
9c9828d3ead6
补 THISNODE 检查
b39d0ee2632d
deferred / skipped → nopage
避免昂贵 reclaim
cc638f329ef6
本地 THP:__GFP_NORETRY
只 compact,不 reclaim
但只挡两类结果
SKIPPED / DEFERRED
performed-but-failed 漏过
两次收紧走对方向,缺口仍在第一步
2f0799a0ffc0 以来以某种形式存在
初次 direct compaction 返回
拿到页 → 成功
直接返回
SKIPPED / DEFERRED
旧检查 → nopage
其它失败
实际执行但没分出页
if (costly_order && (gfp_mask & __GFP_NORETRY)) {
if (compact_result == COMPACT_SKIPPED ||
compact_result == COMPACT_DEFERRED)
goto nopage;
compact_priority = INIT_COMPACT_PRIORITY;
}
否则进入 retry
direct reclaim → local node
然后再次 direct compact
compact_fail 上升
zone_reclaim_mode 类行为
旧路径:成功直接返回;只有 skipped / deferred 提前 nopage
其它失败 → 设置 async priority,继续 reclaim / compact
node 0(本地)
接近 high watermark
空闲页紧张
node 1(远端)
大量空闲内存
可回收 / 可分配
THP 缺页落在 node 0
第一次尝试:__GFP_THISNODE | __GFP_NORETRY
只允许本地 compaction
旧路径:compaction 实际执行但失败
仍然 direct reclaim node 0
尽管 node 1 空闲
customer 报告 / vmstat:compact_fail 上升
本地缺页触发过度回收;呈现 zone_reclaim_mode 类行为
direct compact 失败
page == NULL
SKIPPED / DEFERRED?
是→nopage;否→继续
THISNODE?
是→nopage;否→retry
retry
reclaim + compact
if (costly_order && (gfp_mask & __GFP_NORETRY)) {
if (compact_result == COMPACT_SKIPPED ||
compact_result == COMPACT_DEFERRED)
goto nopage;
旧检查
if (gfp_mask & __GFP_THISNODE)
goto nopage;
新增
compact_priority = INIT_COMPACT_PRIORITY;
}
三个条件同时成立
costly_order
__GFP_NORETRY
__GFP_THISNODE
THP 第一遍的 gfp
不再设置 async priority
也不进入 retry / reclaim
初次 local compact 失败
page == NULL
THISNODE → nopage
结束本地尝试
回到 alloc_pages_mpol
由上层决定下一步
第二步 / 基础页
不再本地回收
第二步不变
gfp 不带 __GFP_THISNODE
可跨节点 reclaim + compact
非 THISNODE 分配也走原路
本地 node 不再被回收
其它节点有空闲时,不强行回收本地
本地缺页保持低延迟
边界:初次 compaction 失败后不再本地重试
允许 direct reclaim(madvised / 同步)→ 第二步;否则基础页
符合 __GFP_NORETRY 的快速失败语义
① 本地
only compact
不 reclaim
② 跨节点
reclaim + compact
madvised / 同步
③ 基础页
任意节点
THP 失败
本地限定 + 初次 compaction 失败 → 停
不再为单个节点制造 reclaim 压力;第二步 / 非 THISNODE 行为不变
mm/page_alloc.c:+14 行,只加一道检查
无量化 benchmark;基于 customer 报告与 vmstat
Fixes: 2f0799a0ffc0(缺口自 node-local THP 恢复以来存在)
第一步的承诺,终于和代码一致
本地大页缺页:要么初次压缩成功,要么按设计转下一步 / 基础页
空格
播放/暂停
←
→
逐动作
R
重播
⚠
1x