空闲页面跟踪 (翻译 by chatgpt)

发布时间 2023-12-12 21:31:48作者: 摩斯电码

原文:https://www.kernel.org/doc/html/latest/admin-guide/mm/idle_page_tracking.html

空闲页面跟踪

动机

空闲页面跟踪功能允许跟踪工作负载访问的内存页面和空闲页面。这些信息对于估算工作负载的工作集大小很有用,进而可以在配置工作负载参数、设置内存cgroup限制或决定在计算集群中放置工作负载时加以考虑。

它由CONFIG_IDLE_PAGE_TRACKING=y启用。

用户API

空闲页面跟踪API位于/sys/kernel/mm/page_idle。目前,它由唯一的读写文件/sys/kernel/mm/page_idle/bitmap组成。

该文件实现了一个位图,其中每个位对应一个内存页面。位图由8字节整数组成,PFN#i处的页面映射到数组元素#i/64的第i%64位,字节顺序为本机。当设置一个位时,相应的页面被视为空闲。

如果自从标记为空闲以来未访问页面(有关“访问”实际含义的更多详细信息,请参见实现细节部分),则认为页面是空闲的。要标记页面为空闲,必须通过向文件写入来设置与页面对应的位。写入文件的值与当前位图值进行OR运算。

只有对用户内存页面的访问才会被跟踪。这些页面包括映射到进程地址空间、页面缓存和缓冲页面、交换缓存页面的页面。对于其他页面类型(例如SLAB页面),尝试标记页面为空闲会被静默忽略,因此这些页面永远不会被报告为空闲。

对于大页面,空闲标志仅在头页面上设置,因此必须读取/proc/kpageflags以正确计算空闲的大页面。

从/sys/kernel/mm/page_idle/bitmap读取或写入将在以下情况下返回-EINVAL:如果您不是从8字节边界开始读写,或者读写的大小不是8字节的倍数。如果写入此文件超出最大PFN,将返回-ENXIO。

也就是说,为了估算工作负载未使用的页面数量,应该:

  1. 通过设置/sys/kernel/mm/page_idle/bitmap中相应位来标记所有工作负载页面为空闲。如果工作负载由进程表示,则可以通过读取/proc/pid/pagemap找到页面,或者通过使用/proc/kpagecgroup过滤外来页面来找到工作负载放置在内存cgroup中的页面。

  2. 等待工作负载访问其工作集。

  3. 读取/sys/kernel/mm/page_idle/bitmap并计算设置的位数。如果要忽略某些类型的页面,例如mlocked页面,因为它们不可回收,可以使用/proc/kpageflags将它们过滤掉。

tools/mm目录中的page-types工具可用于协助此过程。如果使用适当选项最初运行该工具,它将标记所有查询的页面为空闲。然后,工具的后续运行可以显示在此期间已清除其空闲标志的页面。

有关/proc/pid/pagemap、/proc/kpageflags和/proc/kpagecgroup的更多信息,请参见《检查进程页表》。

实现细节

内核内部跟踪对用户内存页面的访问,以便在内存短缺条件下首先回收未引用的页面。如果页面最近通过进程地址空间访问,那么将被视为已引用,此时它所映射到的一个或多个PTE将设置已访问位,或者由内核明确标记为已访问(请参见mark_page_accessed())。后者发生在以下情况下:

  • 用户空间进程使用系统调用(例如read(2)或write(2))读取或写入页面

  • 用于存储文件系统缓冲区的页面被读取或写入,因为进程需要其中存储的文件系统元数据(例如列出目录树)

  • 设备驱动程序使用get_user_pages()访问页面

当脏页面由于内存回收或超出脏内存限制而写入交换或磁盘时,它不会被标记为已引用。

空闲内存跟踪功能添加了一个新的页面标志,即Idle flag。此标志由手动设置,通过向/sys/kernel/mm/page_idle/bitmap写入(请参见用户API部分),并在页面被上述方式引用时自动清除。

当页面标记为空闲时,必须在其映射到的所有PTE中清除the Accessed bit,否则我们将无法检测到来自进程地址空间的页面访问。为避免干扰回收器(如上所述,回收器使用the Accessed bit来提升活跃引用的页面),引入了另一个页面标志,即the Young flag。当由于设置或更新页面的Idle flag而清除PTE的Accessed bit时,将在页面上设置the Young flag。回收器将the Young flag视为额外的PTE Accessed bit,因此将考虑此类页面为已引用。

由于空闲内存跟踪功能基于内存回收逻辑,因此仅适用于在LRU列表上的页面,其他页面将被静默忽略。这意味着如果用户内存页面被隔离,它将被忽略,但由于通常不会有很多这样的页面,这不应明显影响整体结果。为了不阻塞空闲页面位图的扫描,可能也会跳过锁定页面。