软脏PTEs¶
软脏位是PTE上的一个位,用于跟踪任务写入了哪些页面。为了进行此跟踪,需要
清除任务PTEs中的软脏位。
这通过向目标任务的
/proc/PID/clear_refs
文件写入“4”来完成。等待一段时间。
从PTEs中读取软脏位。
这通过从
/proc/PID/pagemap
读取来完成。64位四字中的第55位是软脏位。如果设置,则自步骤1以来相应的PTE已被写入。
在内部,为了进行此跟踪,当软脏位被清除时,PTEs中的可写位也会被清除。因此,在此之后,当任务尝试修改某个虚拟地址的页面时,会发生#PF(页错误),内核会在相应的PTE上设置软脏位。
请注意,尽管在清除软脏位后,任务的所有地址空间都被标记为只读(r/o),但在此之后发生的#PF(页错误)处理速度很快。这是因为页面仍然映射到物理内存,因此内核所做的只是发现这一事实,并在PTE上同时设置可写位和软脏位。
虽然在大多数情况下,通过#PF(页错误)来跟踪内存变化已经足够,但仍然存在一种可能丢失软脏位的情况——一个任务取消映射之前已映射的内存区域,然后在完全相同的位置映射一个新的区域。当调用unmap时,内核会内部清除PTE值,包括软脏位。为了通知用户空间应用程序此类内存区域的更新,内核总是将新的内存区域(和扩展的区域)标记为软脏。
此功能被检查点-恢复项目积极使用。您可以在http://criu.org找到更多详细信息。
-- Pavel Emelyanov,2013年4月9日