背景
vmpressure 用回收的 scan:reclaim 比值推断内存压力:扫描了很多页却没回收到几个,就认为系统吃紧。一旦判定有压力,它会施加 socket pressure,让 TCP 收紧接收窗口、节流网络吞吐。这个机制对 order-0 与低阶回收是合理的:扫得多收得少,确实像是内存不够。
┌─────────────────────────────────┐
│ 高阶分配在碎片化系统触发回收 │
└────────────────┬────────────────┘
▼
┌─────────────────────────────────┐
│ 扫描多、回收少,比值难看 │ 但系统其实有大量空闲,差效率只怪碎片
└────────────────┬────────────────┘
▼
┌─────────────────────────────────┐
│ vmpressure 据此断言 socket 压力 │ TCP 被不必要地节流,接收窗口卡死
└─────────────────────────────────┘
但高阶(costly order,超过 PAGE_ALLOC_COSTLY_ORDER)分配是另一回事。它主要靠 compaction 整理出连续页才成功,而不是靠 reclaim。在碎片化的系统上,高阶回收天然"扫描多、回收少":那些页正在被用、不该释放,差效率反映的是碎片,不是内存压力。可旧 vmpressure 不区分 order,照样拿这个难看的比值去断言 socket pressure,于是明明系统还有大把空闲内存,TCP 却被无谓节流。
问题
- vmpressure 不区分 order,scan:reclaim 比值差就断言 socket pressure
- 高阶回收依赖compaction,碎片化时天然扫描多回收少
- 这种差效率被误判为内存压力
- TCP 被不必要节流,接收窗口卡在最小值
方案
核心是给 vmpressure 加上 order 维度,让它认清"高阶回收的差效率不代表压力"。
旧:所有 order 都判压力
┌────────────────────────────────┐
│ 回收效率差就断言 socket 压力 │
└───────────────┬────────────────┘
▼
┌────────────────────────────────┐
│ 高阶回收的天然低效也被当成压力 │
└────────────────────────────────┘
新:costly order 跳过 socket 压力
┌──────────────────────────────────────┐
│ 只在低阶回收时断言 socket 压力 │
└──────────────────┬───────────────────┘
▼
┌──────────────────────────────────────┐
│ 高阶回收依赖compaction,差效率不再误 │
│ 判 │ memcg 回收与低优先级关键压力不受影响
└──────────────────────────────────────┘
具体地,通过 scan_control 把 order 传进 vmpressure 既有调用点,socket pressure 只在 order <= PAGE_ALLOC_COSTLY_ORDER 时才断言。costly order 的回收本就交给 compaction,它的低效 reclaim 不再触发对 TCP 的节流。
两处要保住不受影响:
- memcg 回收(
try_to_free_mem_cgroup_pages恒为 order 0)无条件通过过滤 vmpressure_prio在内部调 vmpressure 时显式传 order 0,确保来自低回收优先级的关键 pressure 不会被 order 过滤误伤
收益
本 patch 由生产环境一例 net throughput 受损驱动。在一台受影响主机上(~15GB available、零 cgroup 压力、buddyinfo 显示 order 0-3 充足但 order 7+ 为 0,即碎片化),bpf 采集显示 94% 的 vmpressure 调用来自 order-7 kswapd 回收。TCP minimum recv window 阈值为 rcv_ssthresh:19712。
该主机 live-patching 前后的 TCP 连接收窗口状态:
| 状态 | 卡在 minimum recv window 的连接 |
|---|---|
| Before | 723 / 3,843(19%) |
| After(live-patch 后约 30 分钟) | 0 / 3,470 |
错误触发的 socket pressure 被消除,TCP 不再被无谓节流,受影响连接的接收窗口恢复正常。
需说明:这是单一受影响主机的 live-patching before/after,不是 A/B fleet 对比;数据反映的是该碎片化场景下 order-7 回收误节流 TCP 的修正。