我的问题如下:
1.在上下文切换时是否会发生TLB shootdown?我认为不会,因为需要在多处理器CPU上同时执行多个进程。这个假设正确吗?
2.TLB shootdown确切发生的时间是什么时候?
3.谁执行实际的TLB shootdown?是内核(如果是,我在哪里可以找到执行清除的代码?)还是CPU(如果是,是什么触发了这个动作),还是两者都执行(内核执行导致中断的指令,从而使CPU执行TLB shootdown)?
x86 TLB不在核心之间共享,也没有在硬件级别上进行同步。
是操作系统指示处理器刷新其TLB。指示当前处理器相当于调用函数,指示另一处理器相当于发出IPI。
术语“TLB shootdown”特指这种情况(甚至比通常更昂贵),为保持系统一致性,操作系统必须告诉其他处理器使其无效化其TLB,以达到特定处理器的相同映射。
我认为只有新映射影响了某些共享内存时,才需要这样做,否则每个处理器都执行一个进程的不同实例,每个实例具有其自己的映射。
在上下文切换期间,TLB被刷新以删除旧映射,这必须独立于计划运行最后一个处理器。既然处理器正在刷新自己的TLB,这不是TLB shootdown。
必须始终在处理器之间保持一致的共享区域可能是:内核页面、内存映射IO、共享内存映射文件。
执行指令invlpg
、invpcid
、移动到cr0
、cr3
(包括在硬件任务切换期间)或cr4
和VMX转换,都会使TLB失效。关于确切的粒度和语义,请参见Intel Manual 3的第4.10.4节。TLB shootdown是在什么时候发生的?
它发生在操作系统或超级监视程序请求时。
在ISA级别上,某些操作可以执行TLB shootdown(见Intel手册V3 4.10.4和AMD手册V2 5.5.2),从而使一个或多个本地或远程TLB缓存(同一CPU的其他逻辑核心和所有具有TLB并共享相同物理内存地址空间的其他种类的处理器)中的一个或多个TLB条目无效。
还要注意,即使任何未使用过的分页结构条目,都可能被缓存。这可能是由于推测执行或MMU预取而发生的。因此,通常情况下,任何条目都可以随时被缓存或失效。当然,有特定的保证,以便可以管理MMU缓存,并使其与内存分页结构保持一致。
实际的TLB shootdown是由谁执行的?是内核吗?(如果是,则在哪里可以找到执行刷新的代码?)还是CPU?(如果是,则是什么触发了该操作?)还是两者兼备?(内核执行导致中断的指令,进而导致CPU执行TLB shootdown)
正如我之前所说,CPU本身可以在任何时候使任何条目失效。此外,当前特权级(CPL)= 0的软件可以执行与TLB管理相关的任何操作。
Linux内核定义了架构相关的TLB无效函数(/arch/x86/mm/tlb.c)和架构相关的函数(/arch/x86/include/asm/tlbflush.h)。这是因为不同的体系结构提供了完全不同的机制来管理TLBs。要查看Linux内核何时执行TLB失效的示例,请参阅tlb_flush_reason
枚举(注释属于我):
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,
};