v2
2026-09-01
memcgid引用计数移到objcg · v2
将memcg private ID的引用计数从css移到objcg,使swap entry和workingset shadow不再钉住dying memcg,正常释放。
原始补丁链接
子 Patch(6)
1/6
mm/memcg: add a helper to kill the memcgid on offlining
新增 mem_cgroup_private_id_kill(),在 css_offline() 中释放 online 状态持有的 memcgid 引用,使 id 的 get_online/kill/put 引用计数对称。
2/6
mm/memcg: get memcgid reference only after swap charging success
__mem_cgroup_try_charge_swap() 改为 RCU 保护下完成 swap 计费后,再对 online 父 memcg 取 id 引用;失败路径直接返回,避免提前 pin 和撤销。
3/6
mm/memcg: pass the id itself instead of memcg for putting ID
将 mem_cgroup_private_id_put() 改为接收 id 并内部解析 memcg,因为 swap uncharge 只知道 id,且 id 可 outlive memcg,需通过 id 定位引用计数所在 memcg。
4/6
mm/memcg: return the memcg when putting memcgid
让 mem_cgroup_private_id_put() 解析 id 后放引用并返回在线 memcg 给 __mem_cgroup_uncharge_swap(),从而避免该函数二次 xarray 查找。
5/6
mm/memcg: move memcg private ID refcount to objcg
把 memcgid 的引用计数从 css 移到 objcg,xarray 中存 objcg 指针与引用;swap 页不再引用 css,memcg 死后可释放,取回时经 objcg 解析到在线祖先。
6/6
mm/memcg: filter out reparented memcgs got from memcgid
mem_cgroup_from_private_id() 返回的 memcg 可能已被 reparent,需校验其仍拥有该 id,否则返回 NULL;list_lru 跳过、workingset 使用 root。