Linux 内核:重新分配的页框是否已清除?

Linux kernel: is a re-assigned page frame cleared?

当进程结束时,Linux 内核可以重新分配 user-space 页框(物理内存中的页面)到 user-space 页(在另一个进程的虚拟内存。

是否在重新分配之前清除了页框?否则旧内容可能对另一个进程可见,我无法想象这会被允许。一种情况是将页框分配给不断增长的堆,其中旧内容可能在分配的内存中可见。

是的,“re-assigned”物理内存已被清除,但具体如何以及何时清除有点棘手。该页面不会立即清除,而是在另一个进程映射它之后的第一个 write 页面错误时清除。

假设匿名“zero-fill 按需”页面:

  1. 用户程序 A 正在使用物理地址为 PA 的内存页。
  2. 用户程序A终止执行,内核收回内存,物理内存内容仍未改变
  3. 用户程序 B(或者甚至是 A,无所谓)启动并请求一个内存页。
  4. 内核为请求的页面创建一个虚拟映射。
  5. 用户程序B写入映射,导致写页错误。
  6. 内核分配内存,并获得物理地址为 PA 的物理页面,与第 1 点相同(非常合理的情况,因为最近释放的页面位于页面缓存中以供重用)。
  7. 内核清除页面(zeroing-out 任何以前的内容)并相应地更新虚拟映射(页表等)。

所以实际的清除是“延迟”发生的,可能比释放内存并由内核收回内存(第 2 步)的时间(第 2 步)要晚很多(第 2 步)。

注意:第一个 read 页面错误会发生什么映射是一个完全不同的故事。内核总是保留一个完全清零的物理页面(称为“零页面”),并创建到该页面的虚拟映射。每个需要它的进程都会发生这种情况,因此零页在不同进程的多个 VMA 中被映射了很多次。这样做是为了提高性能(不需要 zero-out 任何东西)和节省内存(在发生写入之前不需要分配新页面)。


关于写入错误,也就是页面实际被清除时,内核中可能的代码路径之一是: