软脏 PTEs

软脏是 PTE 上的一个位,它有助于跟踪任务写入的页面。为了进行此跟踪,应该执行以下操作

  1. 清除任务 PTE 中的软脏位。

    这是通过将“4”写入相关任务的 /proc/PID/clear_refs 文件来完成的。

  2. 等待一段时间。

  3. 从 PTE 读取软脏位。

    这是通过从 /proc/PID/pagemap 读取来完成的。64 位 qword 的第 55 位是软脏位。如果设置,则自步骤 1 以来已写入相应的 PTE。

在内部,为了进行此跟踪,当清除软脏位时,将从 PTE 中清除可写位。因此,在此之后,当任务尝试在某个虚拟地址修改页面时,会发生 #PF,并且内核会在相应的 PTE 上设置软脏位。

请注意,虽然在清除软脏位后,所有任务的地址空间都被标记为 r/o,但之后发生的 #PF 会被快速处理。这是因为页面仍然映射到物理内存,因此内核所做的只是找出这一事实并在 PTE 上设置可写位和软脏位。

虽然在大多数情况下,通过 #PF 跟踪内存更改已足够,但仍然存在一个可能丢失软脏位的情况 -- 任务取消映射先前映射的内存区域,然后在完全相同的位置映射一个新的内存区域。当调用取消映射时,内核会在内部清除 PTE 值,包括软脏位。为了通知用户空间应用程序有关此类内存区域更新的信息,内核始终将新的内存区域(和扩展的区域)标记为软脏。

此功能被检查点恢复项目积极使用。您可以在 http://criu.org 上找到有关它的更多详细信息

-- Pavel Emelyanov,2013 年 4 月 9 日