superblock shrinker
SHRINKER_MEMCG_AWARE
super_cache_scan/count
nr_cached_objects
每 memcg
shrink_slab_memcg
per (memcg, node)
dentry/inode LRU
可回收
钩子
btrfs extent map
shmem huge
xfs inode
计数 + 回收
背景
superblock shrinker 同时驱动 dentry/inode 与 fs 钩子
钩子未必响应 memcg
0baad · blanket 门控
非 root context
一律跳过钩子
只在 global/root 调用
假设
钩子都全局
不响应 sc->memcg
per-memcg 白跑
省掉
实现
super_fs_objects_eligible
sc->memcg NULL/root
scan/count 都跳过
一刀切
引入
0baad6f9b997 · v7.3-rc1
对所有文件系统一刀切
例外 · XFS
XFS inode 回收
按 per-memcg 驱动
释放 memcg-charged slab
xfs hook
xfs_fs_nr_cached_objects
xfs_fs_free_cached_objects
不检查 root
有意 per-memcg
被误判
被归为全局
非 root 跳过
inode 回收断
slab 积压
0baad 误伤
XFS 是 memcg-aware
blanket 假设错误
后果 · short-circuit
super_cache_count
XFS 钩子被跳过
每 memcg inode 回收断
per-memcg context
每个 memcg
每个 node
重复 count
重复排队
结果
charged slab
回收路径跳过
压力不释放
回收失效
问题
0baad 后 XFS 每 memcg 回收被短路
memcg-charged slab 无法回收
补删 · 641aade
641aade99f06
v7.3-rc4
补删 helper 与两处调用
0ef8faff490b
v7.2-rc5 · 门控
helper 加入
未删 fs/super.c
单独 no-op
641aade99f06
删 super_fs_objects_eligible
scan 一处
count 一处
XFS 恢复
补删
0ef8 合入时 removal 丢失
641aade 才真正删掉
下放 · btrfs/shmem
btrfs_nr_cached_objects
shmem_unused_huge_count
非 root 返回 0
btrfs
evictable_extent_maps
filesystem-global
non-root 返回 0
保留旧效果
shmem
shrinklist_len
per-superblock
non-root 返回 0
保留旧效果
下放
两个全局计数器自己跳过
不再动 fs/super.c
helper · root check
mem_cgroup_shrink_is_root
sc->memcg NULL
或 root
why
避免 open-code
各 fs 复用
语义清楚
未来可独立解除
use
btrfs
shmem
XFS 不用
放行
helper
memcontrol.h
判断只在回调里
预期收益 · 无 benchmark
641aade99f06 恢复 XFS 回收
pressure relief 恢复
btrfs/shmem 行为不变
XFS
每 memcg inode 回收
恢复
memcg-charged slab
压力释放
边界
无性能数据
只有逻辑推断
不改 dentry/inode LRU
只改钩子门控
空格
播放/暂停
←
→
逐动作
R
重播
⚠
1x