TLB 击落的确切时间是什么时候?
当操作系统或管理程序请求它时发生。
在 ISA 级别,某些操作可以执行 TLB 击落(参见 Intel 手册 V3 4.10.4 和 AMD 手册 V2 5.5.2),从而使一个或多个本地或远程 TLB 缓存中的一个或多个 TLB 条目无效(那些同一 CPU 的其他逻辑内核和所有其他类型的具有 TLB 并共享相同物理内存地址空间的处理器)。
还要注意,任何分页结构条目都可以被缓存,即使它还没有被任何退休指令访问。这可能是由于推测执行或 MMU 预取而发生的。因此,一般来说,任何条目都可以随时被缓存或失效。当然,也有特定的保证,以便 MMU 缓存可以被管理并与内存中的分页结构保持一致。
谁执行实际的 TLB 击落?是内核吗(如果是,在哪里
我可以找到执行刷新的代码吗?)还是 CPU(如果
那么,是什么触发了动作)还是两者兼而有之(内核执行
导致中断的指令,进而导致 CPU
执行 TLB 击落)
正如我之前所说,CPU 本身可以随时使任何条目无效。此外,当前权限级别(CPL)=0的软件可以执行任何与TLB管理相关的操作。
Linux内核中TLB失效简介
Linux 内核定义了依赖于体系结构的 TLB 无效函数 (/arch/x86/mm/tlb.c) 和依赖于体系结构的函数 (/arch/x86/include/asm/tlbflush.h)。这是因为不同的架构为管理 TLB 提供了截然不同的机制。要查看 Linux 内核何时执行 TLB 失效的一些示例,请参阅tlb_flush_reason 枚举(cmets 是我的):
enum tlb_flush_reason {
// The memory descriptor structure mm of the current process is about to change.
// This occurs when switching between threads of different processes.
// Note that when mm changes, the ASID changes as well (CR3[11:0]).
// I'd rather not discuss when context switches occur because it's a whole different topic.
// TLB shootdown only occurs for the current logical core.
// The kernel sometimes can optimize away TLB flushes on a process-context switch.
TLB_FLUSH_ON_TASK_SWITCH,
// Another logical core has sent a request to the current logical core
// to perform a TLB shootdown on its TLB caches.
// This occurs due to a KVM hypercall. See TLB_REMOTE_SEND_IPI.
TLB_REMOTE_SHOOTDOWN,
// Occurs when one or more pages have been recently unmapped.
// Affects only the local TLBs.
TLB_LOCAL_SHOOTDOWN,
// This occurs when making changes to the paging structures.
// Affects only the local TLBs.
TLB_LOCAL_MM_SHOOTDOWN,
// Occurs when the current logical core uses a KVM hypercall to request
// from other logical cores to perform TLB shootdowns on their respective TLBs.
TLB_REMOTE_SEND_IPI,
// This equals to the number of reasons. Currently not used.
NR_TLB_FLUSH_REASONS,
};
在其他情况下内核会刷新 TLB。很难列出完整的清单,而且我认为没有人列出过这样的清单。
Linux 内核实现了惰性 TLB 刷新技术。其基本思想是,当修改进程的分页结构时,内核会尝试将 TLB 击落延迟到该进程中的线程即将被安排在使用模式下执行的时间点。
Linux 内核当前使用以下四种方法之一在需要时刷新与当前逻辑内核关联的 TLB:
- 将 CR3 的当前值写入 CR3。虽然这不会更改 CR3 中的值,但它会指示逻辑核心刷新所有与 CR3 中具有相同 PCID 的非全局 TLB 条目。
- 禁用 CR4.PGE,然后将 CR4 的当前值写入 CR4,然后重新启用 CR4.PGE。这具有刷新所有 PCID 和全局条目的所有 TLB 条目的效果。如果支持 INVPCID,则不使用此方法。
- 使用 INVPCID 指令类型 0 使给定 PCID 和虚拟地址的 TLB 条目无效。
- 使用 INVPCID 指令类型 2 使所有 TLB 条目(包括全局变量和所有 PCID)无效。
目前没有使用其他类型的INVPCID。
相关:Do the terms tlb shootdown and tlb flush refer to the same thing.
除了软件启动的 TLB 条目失效之外,英特尔手册第 3 卷第 4.10.2.2 节针对 P6 微架构和大多数更新的微架构:
处理器不需要实现任何 TLB。确实实现的处理器
TLB 可以随时使任何 TLB 条目无效。软件不应该
依赖于 TLB 的存在或 TLB 条目的保留。
据我所知,AMD 手册中没有这样的声明。但也没有提供关于 TLB 整体保留的保证,因此我们可以对 AMD 处理器得出相同的结论。