-
page_pool 回收不再依赖 skb 标记
skb->pp_recycle 让每个驱动手动标记 page_pool 页,克隆、拆分与拼接时还要传播;改为按 netmem 自身 pp_magic 识别并统一到 netmem_inc_ref()/netmem_dec_ref(),回收路径在类型检查后用 __netmem_to_page() 省掉两次 WARN 与 out-of-line 调用,bench_page_pool_simple 的 cache recycle 从 40 cycles 降到 30-31 cycles(约 -24.7%),ptr_ring 路径约 -8.6%
-
避免 smart scan 漏掉重复页
把 smart scan 的跳过轮次从每页私有倒计时改成按全局扫描号对齐,周期取 2、4、8,不管 age 差多少,两页最迟每 8 轮同轮相遇;420 对相隔 0 到 20 轮变相同的页从 361/334 对变成全部合并,代价是永不合并的内存上 ksmd CPU 多约 10%
-
与 PTE table 回收竞争时不要跳过 uffd marker 安装
UFFDIO_WRITEPROTECT 为 none PTE 装 marker 前会先 pte_alloc();空 PTE table 可能在这之后被并发回收,旧代码随即因 pmd_none 跳过整段,marker 没装上却返回成功。补丁在需要 populate 时不再提前退出,让 change_pte_range() 的 -EAGAIN 重试重新分配,避免写保护静默丢失
-
防止 uffd poison marker 丢失
注销 userfaultfd 后 poison marker 仍留在页表里,但 fork、hugetlb PMD 共享和 shmem page-table retraction 都可能把它丢掉。补丁新增粘滞的 VM_MAYBE_UFFD_POISON,在安装 marker 前置位并在注销、split/merge、fork 后保留,用它禁止 PMD 共享、强制 fork 复制页表;retraction 则改成实地扫描 PTE 表是否为空
-
用连续内存加速 ioremap 与 vmalloc 及 vmap
用单次页表遍历按粒度设大页并对连续页批量映射,并处理 PMD 边界与映射期间的并发读取,让大缓冲 vmap 加速约 8 倍且 TLB 压力骤降
-
kmem accounting 关闭时按整个 NUMA 节点比较 shadow node 数
关闭 kmem accounting 后,shadow_nodes 的 list_lru 不再 memcg-aware,所有 shadow node 挂在 NUMA 节点的同一个链表上;旧代码仍用 root memcg 的局部页数算上限,导致大量 shadow node 被回收、refault 信息丢失。补丁只在 list_lru 真正 memcg-aware 时使用 memcg 页数,否则按整个 NUMA 节点比较
-
防止拆分 folio 时丢失 PG_waiters
在 split 路径改用原子的 SetPageHead() 设置 PG_head,避免并发设置的 PG_waiters 被非原子读改写覆盖,消除该竞态下 migration_entry_wait() 等待者永久阻塞
-
在作废 DAX 条目前解除映射
把 DAX 区间的 unmap 提到 invalidate 之前,并在丢弃最后一个 association 前检查 folio refcount,避免拆散仍在使用的 folio,消除 reflink CoW 写触发的两类 DAX WARNING 与 first tail page 元数据破坏
-
用批处理框架加速 large folio 的 zswap 存储
large folio 的 zswap 存储改为最多 4 页一批,压缩上下文每批只加锁一次,entry 分配与记账批量完成,acomp 新增 unit_size 与 batch_size 支持多页请求;zswap_store() 的 PMD folio 延迟 p50/p95/p99 分别降低 5.02%/3.58%/7.97%,批量压缩每页 p99 比 baseline 单页压缩低 15.16%
-
限制 khugepaged 遍历 VMA 时的 mmap_lock 持锁时间
khugepaged 把扫描断点存进每个 mm 的槽位并在锁竞争时从断点续扫,每走过预算四分之一的 VMA 检查一次竞争、有人在等才放锁重取,大量小 VMA 的 mm 折叠耗时从 10.8s 降至 3.6s,单次持锁从 95ms 降至 170us
-
为 RSS 引入层级 per-CPU 计数器
把 per-mm RSS 的 percpu_counter 换成层级 per-CPU 计数器,近似误差从 O(n²) 降到 O(n log n),384 逻辑 CPU 的上界为 158.5MB;未激活的单线程 RSS 精确且零 per-cpu 内存,默认 upstream 基线下 +1 更新 288ns→26ns,random ±32 385ns→135ns
-
匿名 THP 的 PMD 级 swap entry
以 PMD 级 swap entry(HPAGE_PMD_NR 连续 slot 的紧凑编码)为匿名 THP swap-out 整段占位,让 swap-in 直接恢复 PMD 映射,避免拆 PMD 与后续 khugepaged collapse;swap 密集基准下聚合吞吐提升 312.2%(4.12 倍),major fault 减少 87.4%。
-
fork 时像复制 PTE 一样复制 PMD 映射
fork() 的 PMD 大页复制与 PTE 路径对齐,file THP 不再跳过留给子进程逐 PMD 缺页,改为页表锁内用 vm_normal_page_pmd() 判别映射类型后直接复制,rmap 按一个 PMD 计数,写保护与页表 deposit 等收尾与 PTE 路径一致,顺带关闭 special PMD 无锁读取与驱动 zap 的竞态;4GB shmem THP 场景 fork 单次耗时 86-129 us 升至 230-355 us,fork 加子进程全部读取总耗时 2380-2620 us 降至 820-930 us
-
不拿 folio 引用读 page cache
多 CPU 对同一文件的小块读都在同一 folio 的 refcount 上 take 再 drop,refcount 所在 cacheline 在 CPU 间弹跳,tmpfs 每次读还要拿 folio lock;给读会反复命中的 hot folio 打上 PG_rcu_free,其释放挂进每 CPU 队列等一个 RCU 宽限期后才真正归还,读路径在 RCU 读侧经标记、i_size、槽位三道确认后不拿引用直接拷贝,并把 splice、fuse 等绕开释放的复用入口堵上;ext4 的 64 线程 16 字节读从 17M 提升到 70M reads/s,tmpfs 从 1.5M 提升到 69M