OS 在逐出受害页面时如何更新相应的页面 table?

How does the OS update the appropriate page table when it evicts a victim page?

在使用虚拟内存的 OS 中,每个进程都有一个页面 table。每个页面 table 将进程的虚拟内存页面映射到系统的物理内存页面,并指示给定页面当前是否有效(加载到内存中)。

假设内存 运行 低并且 OS 需要选择一个页面从物理内存中逐出。为此有不同的算法。例如,FIFO、LRU。一旦 OS 选择要驱逐的页面,它如何使对该页面的任何现有引用无效?

如果受害页面当前被活动进程使用,则 OS 必须使当前进程页面 table 中的映射无效。如果受害者页面当前被另一个进程使用,OS 必须使另一个进程页面 table 中的映射无效。在任何情况下,OS 如何确定要更新哪个页面 table(如果有),以及它如何在不进行线性搜索的情况下知道映射在该页面 table 中的位置?

从本演示文稿的幻灯片 22 开始有 x86 页面 table 结构的详细描述:

http://www.scs.stanford.edu/12au-cs140/notes/l8.pdf

我还找到了一些有用的虚拟内存概述:

http://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/9_VirtualMemory.html http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Memory/virtual.html

没有答案的类似 Stack Overflow 问题:

how does linux update page table after context switch

其实你问的是反向映射。例如,在 Linux 中,您可以找到 匿名页面 的有用函数 try_to_unmap_anon Inside page descriptor there is a field called mapping. This field is anon_vma。如您所见,这不仅仅是普通的结构,还是一个列表条目。一页可能有多个anon_vmas(参见try_to_unmap_anon):

list_for_each_entry(vma, &anon_vma->head, anon_vma_node)

每页映射正好一个。所有这些 vmas 链接到列表中。这就是内核如何知道哪些进程(及其页表)在起作用。 现在关于内核如何确定虚拟地址......再次可以在这里找到答案:vma_address

233         pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
234         unsigned long address;
235 
236         address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);

所以我们现在可以很快回答你的问题:为了不进行页表扫描,内核将它需要的所有内容(用于快速获取)存储在页面描述符(struct page)中。

通常 OS 会选择一个进程首先减少内存。然后它将从该进程中选择页面。然后它知道要使用的页面 table。

你建议选择一个页面然后找到哪个进程。这通常发生在具有可分页内核的系统中。在这种情况下,系统页面 table 由所有进程共享。