You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核中页缓存(page cache)、struct address_space与内存控制组(memory cgroups v2)的关联及相关技术疑问

Linux页缓存与Cgroup v2的关系详解

咱们从你提到的几个核心疑问逐个拆解,结合内核代码逻辑来解释:

1. 每个控制组是否拥有独立的页缓存?

答案是否,但每个cgroup会独立管理属于自己的页缓存页面。

页缓存本身是全局的、基于文件/struct address_space的缓存机制,不会为每个cgroup单独创建一套页缓存实例。不过,当cgroup内的进程产生页缓存页面时(比如读取文件),这些页面会被标记上所属的mem_cgroup,并且每个mem_cgroup会维护自己的LRU链表——其中就包含了属于该cgroup的页缓存页面、匿名页面等各类内存页面。

你提到的mm/vmscan.c里的shrink_node_memcgs函数,核心逻辑就是遍历当前节点下的各个mem_cgroup,针对每个mem_cgroup的LRU链表进行页面回收,这也印证了cgroup是按归属关系管理页缓存页面,而非拥有独立的页缓存。

2. 页缓存中的所有页面是否均属于同一个控制组?

答案也是否。

一个struct address_space对应一个文件的页缓存(或类似缓存对象),如果不同cgroup的进程都访问这个文件,新生成的页缓存页面会归属到发起读写操作的进程所在的cgroup。也就是说,同一个address_space下的页缓存页面,可能分属多个不同的mem_cgroup。

举个例子:cgroup A里的进程读取了文件X的前4KB,生成的页缓存页面属于cgroup A;之后cgroup B里的进程读取文件X的后4KB,生成的新页面就属于cgroup B。这两个页面都属于同一个address_space,但分属不同的cgroup。

3. 如何确定给定struct address_space所关联的控制组?

这里要明确:struct address_space本身并不直接关联某个固定的mem_cgroup,因为它的页面可能分属多个cgroup。

如果要确定某个具体页缓存页面所属的cgroup,你可以通过struct page结构体中的mem_cgroup指针(在cgroup v2中,这个指针直接指向该页面归属的mem_cgroup实例)来获取。但绝对不能通过“取address_space的第一个页面来确定整个address_space的关联cgroup”——因为前面已经说明,同一个address_space的页面可能属于不同的cgroup,这种方式得到的结果片面且不准确。

如果需要遍历某个address_space下所有页面的归属cgroup,你需要遍历该address_space的页面链表(比如通过address_space->i_pages),逐个检查每个page的mem_cgroup字段。

内容的提问来源于stack exchange,提问作者wxz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 22:49:05