- TLB介绍
- TLB是位于内存中的页表的cache,如果没有TLB,则每次取数据都需要两次访存(查页表获得物理地址+取数据),下图是TLB在整个系统中的示意图。
-
-
x86_64上的TLB
-
普通模式
-
Global Pages
-
当CR3寄存器被修改时,TLB就被flush掉;
-
然而有些经常使用的或则比较关键的pages不想被flush,则可以通过标识为global pages来实现;
-
更改CR3寄存器只flush非global的pages;
-
TLB管理
-
INVLPG用来无效掉某个TLB项,包括标识为gobal的项;
-
修改CR3可以flush除global外的所有项;
-
虚拟机模式(暂不讨论)
-
Linux x86_64的TLB管理
-
flush_tlb() flushes the current mm struct TLBs
-
flush和正在运行的进程相关的TLB的所有项(除了global的),包括本cpu的,和其他可能运行此进程的cpu的TLB
-
本cpu通过IPI通知其他cpu
-
flush_tlb_all() flushes all processes TLBs
-
flush系统内所有cpu的TLB(包括global项)
-
flush_tlb_mm(mm) flushes the specified mm context TLB's
-
flush所有与mm相关的TLB
-
flush_tlb_page(vma, vmaddr) flushes one page
-
flush所有包含此page的TLB的那个项
-
flush_tlb_range(vma, start, end) flushes a range of pages
-
flush一段范围的pages
-
但是目前做不到,只能将全部vma相关的pages flush掉
-
flush_tlb_kernel_range(start, end) flushes a range of kernel pages
-
flush一段范围的kernel pages
-
目前等价于flush_tlb_all()
-
flush_tlb_others(cpumask, mm, va) flushes TLBs on other cpus
-
flush其他cpu上的tlb
-
context switch
-
如果切换前后的两个进程地址空间不一样,则需要加载新进程的页表物理首地址到CR3寄存器,从而导致本cpu的TLB flush(除global pages)
-
如果地址空间一样(比如同一个进程的两个线程),则分两种情况
-
next->cpu_vm_mask的当前cpu位为0,那么需要重新加载CR3寄存器;
-
否则不用;
-
(cpu_vm_mask表示此进程正在哪些cpu上运行,如果为0则表示已放弃此cpu,而如果其他cpu发关于此进程的TLB flush IPI,这个cpu都是收不到的,所以需要加载CR3,以确保TLB没有脏项)