当我们处于用户模式并且发生页面错误时,我有点困惑。
IIRC,当TLB尝试将我的(用户空间)虚拟地址映射到物理地址时,将生成页面错误,并且它将失败。
然后生成一个异常,该异常将由OS同步处理。但是现在的问题是:此异常处理程序代码的地址及其相关数据很可能也不会在TLB中!
这是递归的还是此内存地址的内核范围受不同规则的约束(例如,虚拟/物理内存之间的自动映射,以避免需要使用TLB?)
谢谢!
答案 0 :(得分:4)
否,Linux不会交换内核内存。(由于这个原因和类似原因,例如,确保在任何访问内存的随机指令之前不会运行页面错误处理程序)。
确实对某些内核内存进行分页的OS肯定需要将页面错误处理程序,页表和磁盘I / O代码保留在内存中...
此异常处理程序代码及其相关数据也将不在TLB中!
您正在将页面遍历(在TLB未命中时)与页面错误(虚拟页面的条目无效或权限不足,如果有必要,在页面遍历之后获取)相混淆。
在x86和大多数其他(?)ISA上,页面遍历由硬件完成。参见What happens after a L2 TLB miss?。
操作系统为CPU提供顶级页表的物理地址(例如,在x86上带有mov cr3, rax
),并且CPU透明地处理所有其他内容。 (唯一的软件TLB管理是在修改内存中的页表条目之后使可能缓存的条目无效。例如x86 invlpg
)
硬件页表管理,当数组上的循环接近页面边界时,CPU 可以推测地执行TLB遍历,而不必等到实际负载触及下一页。乱码执行和很多其他好处可以部分隐藏页面漫游延迟。 Skylake甚至有2个“步走”单元,因此它可以并行处理2个TLB遗漏(这两者都是投机性或需求性的。)
在具有软件页面遍历的ISA上,TLB缺失处理程序与页面错误处理程序是分开的。
例如,在MIPS上,有一个特殊范围的地址与正常内核虚拟地址不同地映射:
如果地址以
0b100
[最高3位]开头,则转换为最低512 MB的物理内存,并且不经过TLB。 (缓存和未映射)。称为kseg0
。用于内核指令和数据。MIPS TLB处理-https://people.csail.mit.edu/rinard/teaching/osnotes/h11.html
(设置了高位的MIPS地址只能由内核代码使用,用户空间访问错误。即high-half kernel被引入MIPS。)
这有点像将512MiB超大页面映射到烘焙到硬件中的低物理内存。显然,内核希望将其页面查找数据结构保持在该范围内,但是它可以使用所需的任何数据结构,例如根据开始/长度。
答案 1 :(得分:0)
首先,在考虑软件时,您应该将TLB排除在外。 TLB是硬件组件。 TLB中没有映射的事实并不会自动导致页面错误。
第二,在某些硬件上,常见的是多页错误。当处理器允许分页表时,就会发生这种情况。因此,您可以在页面上遇到页面错误,并且在读取页面表时遇到更多或更多页面错误。支持此功能的处理器使用各种机制来解决可以解决页面问题的页面问题。
然后生成一个异常,该异常将由OS同步处理。但是现在的问题是:这个异常处理程序代码的地址及其相关数据很可能也不会在TLB中!
每个操作系统都必须确保其页面错误处理程序保留在物理内存中。
这是递归的还是此内存地址的内核范围受不同规则的约束(例如,虚拟/物理内存之间的自动映射,以避免需要使用TLB?)
在某些处理器上,系统地址空间范围的映射与用户空间的映射不同。这是避免分页页表的鸡肉和鸡蛋问题的方法之一。