linux - 页面错误处理程序可以生成更多页面错误吗?

标签 linux operating-system cpu-architecture tlb page-fault

当我们处于用户模式并且发生页面错误时,我有点困惑会发生什么。

IIRC,当 TLB 试图将我的(用户空间)虚拟地址映射到物理地址但失败时,将生成页面错误。

然后它会生成一个将由操作系统同步处理的异常。但现在的问题是:这个异常处理代码的地址及其相关数据很可能也不在 TLB 中!

这是递归的还是这个内存地址的内核范围受制于不同的规则(例如,虚拟/物理内存之间的自动映射以避免需要使用 TLB?)

谢谢!

最佳答案

不,Linux 不会换出内核内存。(出于这个原因和类似的原因,例如确保页面错误处理程序不会在访问内存的任何随机指令之前运行)。

确实对某些内核内存进行分页的操作系统肯定需要将页面错误处理程序、页表和磁盘 I/O 代码保留在内存中...


this exception handler code plus its associated data are also not going to be in the 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 上,有一个特殊的地址范围,其映射方式与普通内核虚拟地址不同:

If address starts with 0b100 [top 3 bits], translates to bottom 512 Mbytes of physical memory and does not go through TLB. (cached and unmapped). Called kseg0. Used for kernel instructions and data.

MIPS TLB handling - https://people.csail.mit.edu/rinard/teaching/osnotes/h11.html

(具有高位设置的 MIPS 地址只能由内核代码使用,用户空间访问错误。即 high-half kernel 是 MIPS 内置的。)

这有点像将低物理内存烘焙到硬件中的 512MiB 大页面映射。显然,内核希望将其页面查找数据结构保持在该范围内,但它可以使用它想要的任何数据结构,例如基于开始/长度。

关于linux - 页面错误处理程序可以生成更多页面错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55963187/

相关文章:

c - 使用openssl解密文件

php - 用于 php 的内存缓存 - 无法连接

.net - 如何使用 cron 执行 dotnet 应用程序?

c++ - 由于数据的物理布局导致缓存性能下降

terminology - 与字节序混淆 : bits or bytes?

Popen 不起作用后 C 程序在 Fgets 上挂起

c++ - 等待信号量的进程调度

operating-system - 如果我要构建一个新的操作系统,它会具有什么样的功能?

c - 如何让父进程等待所有子进程完成?

x86 - 这些年来,英特尔为何改变静态分支预测机制?