cgroup 内存控制机制与实现详解
源码路径:
rk3588/kernel-6.1/mm/memcontrol.c、vmpressure.c、mempolicy.c、page_counter.c、swap_cgroup.c
内核版本:Linux 6.1(RK3588)
文档目录:linuxDoc/mm/
目录
一、原理
1.1 cgroup v2 内存控制器
memcg 将进程的 RSS、cache、swap、kernel 内存 计入对应 cgroup,支持:
- limit:硬上限,超限触发 reclaim 或 OOM
- high/max:分层压力与上限
- 统计:
memory.current、memory.stat - 继承:子 cgroup 受父级约束
1.2 与全局 MM 的关系
分配页时若设置了 __GFP_ACCOUNT,在 __alloc_pages 返回后调用 __memcg_kmem_charge_page;匿名 fault、cache charge 亦挂钩。
回收时 scan_control 可带 target memcg,优先回收该组页。
1.3 NUMA policy(可选)
mempolicy.c:mbind、set_mempolicy、MPOL_BIND/INTERLEAVE 等,约束分配 node(RK3588 UMA 场景较少用)。
1.4 vmpressure
vmpressure.c 监测 cgroup 或全局的 回收效率,上报 low/medium/critical,供用户态 lmkd 等决策。
二、实现方式
2.1 核心结构 memcontrol.c
| 组件 | 说明 |
|---|---|
struct mem_cgroup |
计数器、层级、OOM 状态 |
page_counter |
可层次化的字节计数(page_counter.c) |
mem_cgroup_charge |
页/account 到 memcg |
try_charge |
分配前检查是否超限 |
mem_cgroup_reclaim |
组内 direct reclaim |
2.2 charge 路径
mem_cgroup_charge/mem_cgroup_charge_skmem- 超限 →
drain_all_stock/ reclaim → 仍失败 → memcg OOM cancel_charge在释放时回退
2.3 kmem accounting
memcg_kmem_enabled() 时 slab 对象可计入 memory.kmem(__memcg_kmem_charge_page 在 __alloc_pages 尾路径)。
2.4 OOM
mem_cgroup_out_of_memory → out_of_memory 且 is_memcg_oom,仅杀该 cgroup 内进程(见 08 文档)。
2.5 swap_cgroup.c
swap 页计入 memory.swap,与 limit 协同。
2.6 list_lru 与 memcg
list_lru.c 提供 per-memcg LRU(inode、dentry 等),文件缓存可按组回收。
2.7 memory-tiers.c(NUMA)
若 CONFIG_NUMA,内存分层与 tier 统计;RK3588 单 node 通常不启用热路径。
三、关键数据结构与接口
| 接口 | 说明 |
|---|---|
mem_cgroup_charge |
页 charge |
get_mem_cgroup_from_mm |
从 mm 取 memcg |
cgroup_file memory.max/current |
cgroupfs |
mem_cgroup_try_charge |
预检查 |
cgroup v2 挂载:/sys/fs/cgroup(unified hierarchy)。
四、RK3588 平台说明
- Android:应用 cgroup 由 lmkd/init 配置,
memory.min/low/high影响杀进程策略。 - 编码服务:可为客户端进程设 memory.max,防止单路拉垮整机。
- PSI + vmpressure:与 07 文档 PSI 结合,做自适应限流。
五、调试与观测
| 路径 | 内容 |
|---|---|
memory.current |
当前用量 |
memory.stat |
anon/file/kernel 分项 |
memory.events |
oom、max 等事件 |
memory.pressure |
pressure 接口(若启用) |
附录:源码索引
| 主题 | 文件 |
|---|---|
| memcg 核心 | memcontrol.c |
| page_counter | page_counter.c |
| vmpressure | vmpressure.c |
| mempolicy | mempolicy.c |
正在加载留言…