背景
SLUB 用 percpu sheaves 替换了旧的 cpu partial slabs,给每颗 CPU 一个快速的对象缓存。sheaves 在某颗 CPU 上有效工作,前提是这颗 CPU 所在的 NUMA 节点已分配了 barn,也就是对象缓存的「仓」。可旧的实现只为有内存(N_MEMORY)的节点分配 barn,因为那里才有节点级的缓存管理结构,仓指针原本就挂在它身上,目标是缓存节点本地对象。
┌──────────────────────────────────────┐
│ per-CPU sheaves 只在有内存的节点建仓 │
└──────────────────┬───────────────────┘
▼
┌──────────────────────────────────────┐
│ 无内存节点没有仓,sheaves 失效 │ 分配退回慢路径,slub 统计大量慢路径
└──────────────────┬───────────────────┘
▼
┌──────────────────────────────────────┐
│ 多节点无内存的系统尤其严重 │ 8 节点仅 2 节点有内存的系统回归
└──────────────────────────────────────┘
这套逻辑在「无内存节点」上断了。当一个 NUMA 节点 online 却没有物理内存时,它没有 barn,sheaves 在这个节点的 CPU 上就失效了,分配不得不退回慢路径。Ming Lei 报告的回归就是这么来的:一台 8 个 online NUMA 节点、却只有 2 个有内存的机器,slub 统计显示出大量慢路径分配。
问题
- percpu sheaves 只在有内存节点建 barn
- 无内存节点没有 barn,sheaves 失效
- 分配退回慢路径,slub 统计可见大量慢路径
- 多节点无内存的系统尤其严重
方案
核心思路是让无内存节点也用得上 sheaves:既要在那里建仓、缓存非本地对象(反正本地对象本就不存在),又要让对象的归还与释放都走得通快路径。
旧:只给有内存的节点建仓
┌────────────────────────────┐
│ 无内存节点没有仓 │
└─────────────┬──────────────┘
▼
┌────────────────────────────┐
│ sheaves 失效,分配走慢路径 │
└────────────────────────────┘
新:所有在线节点都建仓
┌──────────────────────────────────┐
│ 无内存节点也有仓,缓存非本地对象 │
└────────────────┬─────────────────┘
▼
┌──────────────────────────────────┐ 归还按本 CPU 节点定位仓,不再借最近有内存
│ 分配与释放都走 sheaf 快路径 │ 节点
└──────────────────────────────────┘
让无内存节点也有仓
旧实现把仓指针挂在每个有内存节点才有的节点级结构体里,于是只有有内存节点建得了仓。先把这层耦合拆开,让每个在线节点都能独立持有仓;再用一个节点位图记录哪些节点建了仓,并在 CPU 热插拔回调里补建,因为无内存节点正是随 CPU 上线而进入在线状态的。
让对象归还到本节点的仓
仓建好还不够,对象得真的流进来。对象归还的落点原本取「最近有内存节点」,于是无内存节点上的 sheaves 永远收不到对象;改为取本 CPU 所在节点(它可能就是无内存节点),对象就归还到本节点的仓里,不再借最近有内存节点的仓。
让释放也走快路径
分配侧通了,释放侧还堵着。无内存节点上释放对象时,因为对象都是远端的,局部性判定一律不通过,只能走慢路径。可这些节点本就分配不到本地对象,与其一律走慢路径,不如放宽判定、允许远端对象进 sheaves。这条判定被抽成一个共用的内联函数,让归还与释放共用同一套规则。代价是分配侧从 sheaves 拿到的对象平均距离变大:原先释放一律走慢路径时,sheaves 靠 zonelist 顺序回填,能凑到距离更近的对象。
附带的好处:CONFIG_HAVE_MEMORYLESS_NODES=y 的系统上,之前无内存节点借最近有内存节点的 barn,随着无内存节点增多、barn 锁竞争上升;现在各节点有自己的 barn,竞争下降,代价是内存消耗略增。
收益
作者未提供量化 benchmark。从机制与回归动机推断的预期收益:
- 无内存 NUMA 节点上的分配不再因 sheaves 失效而退回慢路径
- 无内存节点上的释放也走 sheaf 快路径,不再总走慢路径
- CONFIG_HAVE_MEMORYLESS_NODES=y 系统上 barn 锁竞争下降(各节点独立 barn)
作者说明回归动机:8 个 online NUMA 节点仅 2 个有内存的系统上,slub 统计显示大量慢路径分配。