延迟分裂队列
THP 暂时不能 split
例如仍被映射
挂起等 shrinker
触发
anon THP
swapin
khugepaged
可分裂页创建
队列
deferred split
等内存回收
再尝试 split
不是立即分裂
背景
延迟不是永远
回收时再处理
旧队列 · per-cgroup
open-coded 队列
每个 cgroup 一条
不区分 NUMA node
组织
memcg 启用时
memcg->deferred_split_queue
spinlock + len
无 node 维度
结果
node 受限回收
扫整个 cgroup
没有交集
其他 node 混入
问题
cgroup 有队列
node 没分开
越界 · 节点受限回收
node 受限分配
回收只看目标 node
队列却跨所有 node
目标
目标 node 有大页
触发 shrinker
本应只扫这里
局限少数 node
越界
扫整个 cgroup
其他 node 的 THP
也被 split
本不该动
问题
目标 node 有页
其他 node 遭殃
护栏 · shrinker bit 不严
set_shrinker_bit
(memcg, node)
只是一道 bit
本意
目标 node 有页
才扫该 memcg
避免空扫
缩小范围
不严
目标 node 一张
即置位
整个 cgroup 队列
仍被扫
关键
bit 只回答有没有
不限定哪张页
方案 · list_lru
deferred_split_lru
per-node × per-memcg
list_lru 原生交集
结构
list_lru
node 子列表
memcg 子列表
扫描取交集
回收
目标 node
目标 memcg
只扫这些页
不再跨 node
改动
队列换成 list_lru
只扫交集
按需 · 建头
首次可分裂页
folio_memcg_alloc_deferred()
一次建全所有 node
调用点
anon fault
swapin fault
khugepaged collapse
vma_alloc_anon_folio_pmd
迁移
所有 node 头已备
跨 node 迁移
无需特殊处理
目标头早就在
设计
一次建全
省去迁移特判
铺垫 · 9 个 patch
series v5
list_lru 先行
主改动最后
准备
caller locking
folio 分配头
anon 循环展平
锁路径整理
修竞态
set_shrinker_bit
cgroup 删除竞态
原 memcg 错位
设到有效 memcg
系列
1 修复 + 7 准备
最后切队列
收益与边界
无性能数据
机制推断
不是 benchmark
预期
不再越界 split
保留更多 THP
TLB 收益
扫描更聚焦
边界
NUMA + cgroup
才有交集问题
无数据不外推
机制收益
边界
作者未给数字
只讲机制预期
空格
播放/暂停
←
→
逐动作
R
重播
⚠
1x