-
用随机偏移补扫采样落空的 pageblock
free scanner 的 stride 采样会与 2 的幂布局混叠而整块漏掉 free page,给颗粒无收的 pageblock 补一次随机相位扫描后,在构造布局下 allocstall 中位数从 86 降到 0,建 100 万文件耗时回到对齐布局水平
-
把 small folio 的 mapcount 递减降为 release ordering
COW 换页要求先摘 PTE、刷 TLB,再减 folio 的 mapcount;把 small folio 的 mapcount 递减从全序 RMW 换成 release RMW,arm64 模拟器上 20,480 次 minor fault 的模拟周期下降 1.54%,真实硬件收益未测
-
修复隔离 CPU 上永不排空的 LRU cache
隔离 CPU 上的 SCHED_FIFO 自旋任务让 per-CPU LRU cache 永远排不空,cpuset.mems 触发的 50GB 页迁移卡在 lru_cache_disable(),PID 1 进 D 状态 3-5 分钟;这组改动恢复 nohz_full 的隔离判定,让隔离 CPU 绕过 per-CPU LRU batch,并让 cpuset 迁移与 fork 不再同步等待,修复后同一复现脚本不再卡住
-
缺页时迁移 device page
HMM pagewalk 单次遍历合并缺页处理与迁移收集,两个入口加标志打通,页表遍历从最多 3 次降为 1 次;nouveau SVM 成为首个驱动消费者
-
per-memcg shrinker unit 按需装进 xarray
每个 memcg 原本在每个 NUMA node 按 shrinker_nr_max 预分配全部 shrinker_info_unit,外加一个同尺寸的 unit 指针数组,而每个 superblock 都注册 1 个 memcg-aware shrinker 且 shrinker_nr_max 只增不减,挂载与 cgroup 多的主机上每个空 cgroup 都在为所有 superblock 付账;先把 unit 挪进 xarray 让扩容不再 realloc 与 RCU 发布,再让 unit 只在 memcg 或其某个后代真正持有某 shrinker 的 list_lru 链表时按需安装,48-CPU 4-node 主机 50000 个 tmpfs 挂载加 20000 个 cgroup 下,空 cgroup 的 unreclaimable slab 从 1.6 MB 降到 34 KB,shrink_slab_memcg() 从 22.8 us 降到 0.5 us
-
降低 MGLRU memcg 轮换的开销
MGLRU 全局回收轮换 memcg 时,尾部插入要关中断持锁遍历目标 bin,数万 cgroup 的服务器上反复触发 soft lockup 与 RCU stall;为每个 bin 缓存尾节点使尾部插入变为常数时间,跳过已在 young generation 的冗余轮换,并在 memcg 扫描之间补调度点,1500 个 memcg 8 线程并发回收基准下吞吐提升 12.7 倍
-
批量 TLB flush 跳过 stale 与 lazy CPU
批量 TLB flush 的 info.mm 为空,无法像 per-mm flush 那样按 loaded_mm 过滤,reclaim、migration、demotion 反复向 stale CPU 发 IPI;batch 记录至多 8 个 mm 并在 flush 前按 loaded_mm 与 lazy 状态过滤 cpumask,112-CPU Skylake 的 reclaim 远程 IPI 从 9,092,156 降到 191,耗时降低 74.3%
-
拆分未充分使用的匿名 mTHP folio
让 deferred split shrinker 按 folio 尺寸判定并拆分至少 2M 的匿名 mTHP,回收未使用内存,同时消除默认配置下的无效入队锁与扫描开销,并按 order 记录 underused 拆分
-
内存降级改用 non-temporal stores
降级路径的 folio 拷贝改用 non-temporal stores 绕过缓存写分配;拷贝原语用 MCE-safe 的 x86 汇编实现,并在发布页表前用 wmb() 排空弱序写;RFC v2 实测 64GB 降级时 CXL 设备读流量从 64GB 降到几乎 0
-
给 memory.reclaim 加源头选择器
tiered memory 系统上 memory.reclaim 只能说「从该 memcg 回收 N 字节」,用户态控制器无法指定从哪些节点施压,进度又只有一个聚合值,层级比例的反馈控制因此失效;新增类型化 source=nodes:<nodelist>,只声明现有 aging 回收流水线施压的源头,不改 demote 或驱逐策略与完成度记账,CXL 机器上 file-cache-CXL-high 的达标率从 1/20 提升到 20/20
-
GUP 批量查找用户页
follow_page_mask 改为一次返回连续页数,PTE 层一次锁遍历整张页表,同 folio 连续 PTE 合并为一次引用抓取,64kB mTHP 提速 12.8 倍,4kB base page 提速 2.3 倍
-
为 zswap 绕过 swap readahead
zswap 与 zram 同为内存型同步后端,但未被标记 SWP_SYNCHRONOUS_IO,仍走 swap readahead 预读无意义的邻居;do_swap_page 改用 swap_entry_synchronous 统一判定同步源,zswap 命中的 entry 直接走 swapin_sync 绕过 readahead,swap thrash 场景构建时间 -15.6%,zswap-in -33%,swap readahead 页数 -93%
-
在编译期折叠页表中改变 pXdp_get 与 pXd_page 的行为
在编译期折叠页表配置(ppc32、arm64 2/3 级)下,让 ptep_get 等对已折叠层返回 dummy entry、提供 pXd_offset_lockless 忽略该值并对 dummy 误用做编译期拦截,消除冗余 READ_ONCE load
-
移除 folio 时只清一次页缓存标记
page_cache_delete() 在 xas_store() 之后无条件调用 xas_init_marks(),但新项为 NULL 时 xas_store() 已经清过标记;4K folio 的常规删除因此把同一份标记清两遍,占清理干净页缓存耗时的约 6%。改为只在存入 shadow 时补清标记,8GiB 4K folio 的 POSIX_FADV_DONTNEED 从 1517ms 降到 1423ms,drop_caches 从 1515ms 降到 1422ms