v4
2026-10-16
zram 压缩上下文重构瘦身 · v4
zram系列优化压缩后端:拆分读写流、共享解压流、预初始化字典及跨对象bounce buffer。
原始补丁链接
子 Patch(12)
1/12
zram: prefix backends printk-s
为各 zram 后端日志统一加 zram 前缀,使如 zstd 分配失败信息能明确来自 zram 后端而非通用库,减少调试混淆。
2/12
zram: remove debugfs entry on init failure
zram_init() 注册块设备失败时删除已创建的 debugfs 项,避免初始化失败路径泄漏 debugfs 条目。
3/12
zram: zstd: do not allocate empty C/D-dictionaries
zstd 后端在未提供字典时不再调用 zstd_create_cdict/ddict_byreference(),避免空字典仍分配约 96KB 至 160KB 内部内存,降低默认内存占用。
4/12
zram: lz4hc: pre-initialize dictionary stream in setup_params
lz4hc_setup_params() 预初始化字典流并存入 params->drv_data,压缩前 memcpy 到每 CPU 流,省去逐页 reset/hash;设备初始化时拒绝超过 64KB 字典,避免每页压缩报 -EINVAL。
5/12
zram: lz4: use LZ4_decompress_safe_usingDict()
lz4 解压改用 LZ4_decompress_safe_usingDict() 并删除每 CPU dstrm;压缩工作区直接放 ctx->context,有字典时用 vmalloc() 分配 cstrm/dict_stream,避免 kmalloc 页数取整多耗约 12KB。
6/12
zram: lz4hc: use LZ4_decompress_safe_usingDict()
lz4hc 解压改用 LZ4_decompress_safe_usingDict(),去掉每 CPU LZ4_streamDecode_t 和 lz4hc_ctx,工作区并入 ctx->context;有字典时用 vmalloc() 避免 256KB 被取整到 512KB,每 CPU 省约 252KB。
7/12
zram: zstd: do not use kvzalloc() for zstd allocations
zstd_custom_alloc() 对大于 PAGE_SIZE 的分配改用 __vmalloc()、小对象用 kzalloc(),避免 kvzalloc() 走 kmalloc 时按 2 的幂页取整,字典场景显著降低 CDict/CCtx/DCtx 内存。
8/12
zram: reset writeback state in zram_reset_device()
zram_reset_device() 现在重置 struct zram 中的回写状态(wb_limit_enable、wb_batch_size、compressed_wb 等),修复这些字段从 zram->stats 移出后 device reset 不再清零的问题。
9/12
zram: split zcomp into separate R/W streams
把 zcomp_strm 拆成压缩 cstrm 与解压 dstrm,并拆分 zcomp_ops 的 cctx/dctx 创建销毁回调,使读写不再争同一 per-CPU 互斥锁,消除 Writer/Reader 优先级反转;上下文独立,内存基本不增。
10/12
zram: introduce shared decompression streams
为 zcomp_dstrm 增加 ->lock 读侧防 CPU 热拔、写侧用于 zcomp_cpu_dead(),以及 ->excl_lock 串行 local_copy/ctx;无解压状态且单页 zsmalloc 对象的读取走共享模式,消除 Reader/Reader 优先级反转。
11/12
zram: allocate bounce buffer for spanning objects
对跨物理页的 zsmalloc 对象,解压时分配临时 bounce buffer 线性化,避免占用受 ->excl_lock 保护的 local_copy;失败才回退独占路径,使无状态后端共享解压几乎覆盖所有读,降低读尾延迟。
12/12
zram: use a singleton compression context for recompression
二级压缩器仅由 dev_lock 串行的 recompress_store() 使用,因此改为只分配单个 recomp_cstream,而解压仍保持每 CPU;去掉未用的每 CPU 压缩上下文和缓冲区,显著节省内存。