swap 读写提交已抽象成 swap_ops
swap_ops
can_merge
submit_write
submit_read
三个钩子,块设备与文件系统各挂各的实现
换出页
swap_iocb
bvec 数组
攒满 SWAP_CLUSTER_MAX
才提交一次
一次 I/O
攒批摊薄提交开销,但不是对所有设备都划算
后面两条改法各自独立:一条治批量,一条治兜转
同步设备:写完立即完成,writeback 位随写随清
zram · 同步 swap 设备
SWP_SYNCHRONOUS_IO:写完立即完成
writeback 位随写随清
不需要等回写完成
LRU 扫描看到真实进展
扫到 writeback 中的 folio 会等它完成
攒批提交
满 SWAP_CLUSTER_MAX 才发
writeback 位滞留
同步设备本不该等
LRU 扫描看不到进展
误以为回收停滞
攒批摊薄开销,却把同步设备的及时性弄丢了
经典 LRU 的扫描循环,正指望 writeback 位及时清除
文件系统 swap:读写要串两层间接调用
NFS / SMB 的 swap 文件
文件系统一侧
mm/page_io.c
通用 swap_ops
文件系统 swap_rw
文件系统的方法
两层间接调用
每次读写都要在通用层兜一次,再进文件系统的 swap_rw
串两层间接调用,路径就长一截 —— 这是第二处低效
两件不相干的事,一次做完
swap_ops 更新
同步设备逐 folio 直写
writeback 位及时清除
文件系统自供 swap_ops
swap 读写直达
一个恢复时序,一个去掉跳转,互不依赖
互不依赖,所以能一次做完
改法一 · swap_add_folio() 的攒批判断
swap_add_folio()
换出页进 bvec 数组
块设备
攒满 SWAP_CLUSTER_MAX 照例提交
批量行为不变
同步设备
每个 folio 进数组后立即提交
不等攒满
块设备照旧攒批,同步设备恢复逐 folio 直写
分支只看设备是否同步,不看文件系统还是块设备
改法二 · 文件系统自供 swap_ops,分两步
① 新增 include/linux/swap_ops.h
把 swap_iocb、swap_ops、swap_io_ctx 的声明开放给 mm/page_io.c 之外的实现
② swap_fs_submit 重构成 swap_fs_prepare_rw()
在调用方栈上初始化 iov_iter;NFS 与 SMB 借此各写各的 swap_ops,激活时经 swap_fs_activate() 挂上
swap 读写直达文件系统,通用层兜转消失
读写不再先经通用 swap_ops 再兜 swap_rw
作者未提供性能数据
以下是从代码逻辑推断的预期收益,不是实测
① 同步设备恢复直写
zram 等设备逐 folio 写完即完成
writeback 位随写随清
LRU 扫描看到真实进展
② 读写路径变短
文件系统 swap 不再串
通用 swap_ops 与 swap_rw
两层间接调用
③ 后端可直接接入
swap_ops 声明独立成头文件
后续其他 swap 后端
可直接接入
收益落在时序与路径上,没有吞吐数字可报
文章只给了机制推断:直写恢复、跳转消失、声明开放
空格
播放/暂停
←
→
逐动作
R
重播
⚠
1x