v4
2026-10-15
新增无后端 xswap 交换设备 · v4
提出无后备文件的 xswap 设备,用稀疏 cluster 数组按需增长,为 zswap 动态提供交换空间。
原始补丁链接
子 Patch(14)
1/14
mm: xswap support for zswap
引入无后备存储的 xswap,swap entry 仅由 zswap 持有;新增 nr_real_swapfiles 控制 zswap writeback 只在有真实 swap 设备时进行,xswap entry 不加入 writeback LRU。
2/14
mm, swap: refactor free_swap_cluster_info to take swap_info_struct
free_swap_cluster_info() 改收 swap_info_struct*,从 si 取字段并在释放后清 si->cluster_info,避免 swapon 错误路径双重释放,也便于 xswap 访问 si->flags。
3/14
mm, swap: back the cluster_info array with a sparse VM_SPARSE area
用 VM_SPARSE 懒映射 xswap 的 cluster_info,新增 CONFIG_XSWAP 及相应字段;find_next_to_unuse()/wait_for_allocation() 只遍历已映射范围,grow 失败清理部分映射。
4/14
mm, swap: add sysfs create interface for xswap
新增 /sys/kernel/mm/xswap/create,按可选优先级创建设备,默认最高,大小两倍 RAM;xswap 在 /proc/swaps 显示并跳过 hibernation,避免真实 swap 先拿到页。
5/14
mm, swap: add xswap grow trigger on cluster allocation
cluster_alloc_swap_entry() 在 85% 使用率时提前 grow VM_SPARSE 映射,避免分配失败路径睡眠;目标 65%,并临时释放 percpu_swap_cluster.lock 以允许映射睡眠。
6/14
mm, swap: add xswap_try_shrink and shrink trigger on cluster free
簇全空时 xswap_try_shrink() 仅在已映射范围使用率≤50% 回收尾部,收到 70% 并保留一个 chunk;少于四 chunk 不 unmap,避免 RCU 开销和反复扩缩。
7/14
mm, swap: free backing pages in xswap_unmap_clusters
xswap_unmap_clusters() 解除 VM_SPARSE 映射前从 PTE 收集并释放 backing pages,避免泄漏;用 kvmalloc_array 或分批栈数组保证 unmap 不失败。
8/14
mm, swap: defer xswap shrink to workqueue to avoid lock recursion
__free_cluster() 持 ci->lock 时 unmap 会导致后续 unlock 访问已解除映射地址,故把 xswap_try_shrink() 推迟到 workqueue,只对 xswap 设备调度并在 swapoff 取消。
9/14
mm, swap: refactor swapoff and add xswap_destroy
从 sys_swapoff() 抽出 __swapoff() 复用拆除逻辑,新增 xswap_destroy() 处理无文件设备,通过 /sys/kernel/mm/xswap/destroy 写 swap type 销毁,需 CAP_SYS_ADMIN。
10/14
mm, swap: require zswap for xswap devices
xswap 页只能存 zswap,若 zswap 不可用则创建 xswap 设备失败,避免 swapout 只消耗 swap entry 而无法释放内存。
11/14
mm, swap: do not give an xswap slot to a cgroup that cannot zswap
swapout 时若 cgroup 不满足 obj_cgroup_may_zswap(),跳过 xswap 改分配物理 swap,避免拿到 zswap 无法填充的 xswap slot,并随 zswap 池余量变化。
12/14
mm, swap: widen swap_info_struct max/pages to unsigned long
将 swap_info_struct 的 max/pages 改为 unsigned long,解除 4K 页下 16TB 限制;read_swap_header() 不再 clamp,xswap 改为限制簇数不超过 UINT_MAX。
13/14
mm, swap: add debugfs counters for xswap
为 xswap 增加 debugfs 计数,输出 clusters_max、clusters_mapped、usage_pages 及 grows/shrinks,便于观察 VM_SPARSE 扩缩阈值;不作为 sysfs ABI。
14/14
mm, swap: let the command line set the xswap device size
A new xswap device is always sized at twice RAM. Add xswap.max= to pick the size of devices created after it: xswap.max=300% three times RAM xswap.max=8G eight GiB Twice RAM is right