Kernel 内核如何知道虚拟地址空间中的哪些页面对应于交换出的物理页面帧?

Kernel 内核如何知道虚拟地址空间中的哪些页面对应于交换出的物理页面帧?,kernel,virtual-memory,memory-management,mmu,Kernel,Virtual Memory,Memory Management,Mmu,考虑以下情况:内核耗尽了物理RAM,需要交换一个页面。它选择最近使用最少的页面框架,并希望将其内容交换到磁盘,然后将该框架分配给另一个进程 让我烦恼的是,这个页面框架通常已经映射到多个进程的多个(相同)页面。内核必须以某种方式找到所有这些进程,并将页面标记为已调出。它是如何做到这一点的 多谢各位 编辑:问题的插图: 在交换进程1和2之前,共享页1位于物理内存帧1中: 现在,系统中的内存已经耗尽,内核通过从第1帧中调出第1页并将其替换为第2页来为进程3分配内存。 为了做到这一点,它必须 1) 查

考虑以下情况:内核耗尽了物理RAM,需要交换一个页面。它选择最近使用最少的页面框架,并希望将其内容交换到磁盘,然后将该框架分配给另一个进程

让我烦恼的是,这个页面框架通常已经映射到多个进程的多个(相同)页面。内核必须以某种方式找到所有这些进程,并将页面标记为已调出。它是如何做到这一点的

多谢各位

编辑:问题的插图:

在交换进程1和2之前,共享页1位于物理内存帧1中:

现在,系统中的内存已经耗尽,内核通过从第1帧中调出第1页并将其替换为第2页来为进程3分配内存。 为了做到这一点,它必须

1) 查找所有流程,请参阅第1页(本案例中的流程1和流程2)

2) 修改它们的页表条目,将“Present”位设置为0,并在Swap中设置第1页位置

所以,我不明白第一步是如何执行的。内核不能只是迭代地查看每个进程的页表,以找到指向第1帧的页表条目。从页面框架到页面表条目应该有某种反向映射

答案是:

页表管理最重要的变化是引入了反向映射(rmap)。将其称为“rmap”是故意的,因为这是“首字母缩略词”的常见用法并且不应该与Rik van Riel开发的-rmap树混淆,后者对股票VM的修改比反向映射多得多

在一句话中,rmap授予了定位所有映射特定页面的PTE的能力,只要给定结构页面。在2.4中,找到映射共享页面的所有PTE(如内存映射共享库)的唯一方法是线性搜索属于所有进程的所有页面表。这太昂贵了,Linux试图避免使用交换缓存时出现问题(参见第11.4节)。这意味着,对于许多共享页面,Linux可能必须交换整个进程,而不考虑页面年龄和使用模式。相反,2.6有一个与每个结构页面关联的PTE链,可以通过该链从引用它的所有页面表中删除页面。这样,LRU中的页面可以通过不要求助于交换整个流程。”

来自“Linux2.6中的新功能”

Linux:

使用交换文件时,页面表条目将更新为一个标记为无效的条目,该条目包含有关交换文件中保存位置的信息。也就是说:
swap\u info
数组的索引和
swap\u映射中的偏移量

x86上的页面表条目类型(
pte_t
)的示例(有点旧)。一些 其中的位被硬件用作标志:

Bit         Function
_PAGE_PRESENT   Page is resident in memory and not swapped out
_PAGE_PROTNONE  Page is resident but not accessable
_PAGE_RW        Set if the page may be written to
_PAGE_USER      Set if the page is accessible from user space
_PAGE_DIRTY     Set if the page is written to
_PAGE_ACCESSED  Set if the page is accessed

另请参见x86-64页表格格式示意图。当低位=0时,硬件会忽略所有其他位,因此内核可以将它们用于任何用途。即使在一个“present”条目中,也有一些被保证忽略的位不会保留给将来的硬件使用,因此内核可以将它们用于自己的目的

想必其他体系结构也类似


简单来说:一个进程指向一个页面,页面就会被更新。因此,这些过程实际上也在更新。当物理页面被请求时,它被交换,因此所有进程也被交换。要点是,当内存被调出时,页表条目不会被删除

您可能会发现其中一些方法很有用:

  • 古斯塔沃·杜阿尔特:
报告(2007年):

  • 虚拟机上的红帽


首先,感谢您的详细回答和链接。我之前已经读过Gustavo博客的大部分帖子,以及Mel Gorman的《理解Linux MM》的相关部分。现在查看您的其他链接。可能是我的问题不太清楚,所以我做了编辑。我明白,PTE会得到更新,但要做到这一点,内核必须首先找到它。所以,我的问题是,它是如何找到PTE的,对应于一个页面框架和流程,拥有它的,只考虑到页面框架?啊哈,我在梅尔·戈尔曼的书中找到了答案!它出现在“Linux2.6的新功能”中:<代码>rmap
就是为此目的而引入的。嗯,我想知道2.6之前我们是怎么生活的…@鲍勃:太好了。就要更新答案了。(被另一个问题弄得有点偏离了方向;)我看看是否也能更新答案。我遇到了同样的问题。。我想知道,
rmap
是否与
倒页表
相同?如果是,那么如何处理共享内存?由于在共享内存中,一个物理帧映射到多个逻辑页,因此我想知道在这种情况下,带有地址空间标识符(ASID)的TLB的作用。ASID是分配给TLB的每个条目的唯一ID,指定使用此帧的进程的ID。FTR:添加一个链接到这篇有用的文章:如果答案作为答案发布,而不是编辑到问题中,那会更好。