how TLB work

之前遇到了linux random kernel panic的问题,原因是TLB的entry对应的page其实已经释放。

VIP是独立的ko,create resource是通过VA接口走到我们ko的allocation接口,

unmap gart后,没有invaliate tlb,再create allocation,使用了 同样的va,从tlb 拿PA,结果write到了已经释放的page上。

invaliate gart cache走的是mmio而不是dma,不用等待dma fence back。

现在inv tlb是在submit task里面做的,改成在map gart或者destory allocation时也做。

这里直接invalidate了tlb,降低了性能。

TLB资料:

http://www.wowotech.net/memory_management/tlb-flush.html

TLB flush操作

扫描二维码关注公众号,回复: 5664430 查看本文章

Linux VM subsystem很多场合要对TLB flush,下面描述了TLB概念,硬件实现,TLB flush的软件接口,内核版本是4.4

1,概念

what's TLB:Translation Lookaside Buffer,

处理器在取址或者执行访问memory指令时需要进行地质翻译,即把虚拟地址翻译成物理地址。

但地址翻译是个漫长的过程,要遍历几个level的translation table,是严重开销。

为提高性能,在MMU增加TLB单元,把地址翻译关系保存在这个高速缓存中,以省略对内存中页表的访问。

why need TLB?

TLB本质是一种cache,cache的存在就是为了更高的performance,

instruction cache,指令缓存,

data cache

translation cache

instruction cache解决cpu获取main memory中的指令数据(地址保存在PC寄存器)的速度慢的问题而设立的。

data cache是为了解决数据访问指令比较慢而设立的。

而这这是事情的一部分,看看程序中数据访问指令的执行过程:

1,将PC的虚拟地址反应成物理地址

2,从memory获取数据访问指令(假设该指令需要访问地址x)

3,将虚拟地址x翻译成物理地址y

4,从location y 的memory获取数据

instruction cache解决了2的性能问题,data cache解决了step 4的性能问题。

复杂的系统会建立各个level的cache来缓存main memory的数据,而他们只加速了2,4步骤,

IC设计师不会放弃1,3的,这也是TLB的由来。

若CPU core发起的地址翻译过程可以在TLB(translation cache)中命中(cahche hit),CPU不需要访问慢速的main memory提高了performance

how TLB work?

图片来自计算机的组成与设计,computer organization and design

当要转换VA到PA时,首先在TLB找是否有匹配的条目,若有,称为TLB hit,则不用再访问页表完成地址翻译。

TLB始终是全部页表的一个子集,所以可能在TLB找不到。

若没有在TLB中找到对应的item,称为TLB miss,就需要访问memory的page table完成地址翻译,同时将翻译结果放入TLB,如果TLB满了,还要设计替换算法决定哪个TLB entry要失效,以加载新的页表项。

TLB entry的内容包括:

1,物理地址,physical page number,这是地址翻译的结果。

2,虚拟地址,virtual page number,用cache的术语描述叫Tag,进程匹配时就是对比Tag。

3,memory attribute,如memory type,cache poliocies, access permissions

4,status bits,如Valid, dirty,reference bits

三,ARM v8的TLB

选择cortex-A72 processor来描述ARMv8的TLB的组成结构和维护TLB的指令。

1,TLB的组成结构,下图是A72的功能block:

A72实现了2个level的TLB, 绿色是L1 TLB,包括L1 instruction TLB(48-entry fully-associative) 和 L1 data TLB(32 entry fully-associative)。黄色block是L2 unified TLB,它要大一些,可荣亚1024个entry,是4-way set-associative的。

当L1 TLB发生TLB miss时,L2 TLB是它坚强的后盾。

2,如何确定TLB match?

地址翻译过程不是VA->PA的映射那么简单,系统中的虚拟地址空间很多,每个地址空间的翻译都是独立的。

1)每个进程有自己独立的VA空间,各进程里,相同的VA翻译成不同的PA。

2)若支持虚拟化,系统中存在一个hostOS和多个guest OS,不同OS间地址翻译不同,

3)

我们可以不考虑复杂的情况,在进程切换、虚拟机切换、secure/normal world切换时,将TLB所有内容全flush(invalidate),这样设计很轻松,但性能下降。

实际设计TLB时,会让TLB entry包含和虚拟地址空间context相关的信息,A72里,满足下面条件,才算匹配了一个TLB entry:

1)请求进程地址翻译的VA page number等于TLB entry中的VA page number

2)请求进程地址翻译的memory space identifier等于TLB entry的memory sppace identifier。

所谓memory space identifier就是区分请求是来自EL3 Exception level,nonsecure EL2 exception level,Sucure and nonsucrue EL0.。。。。

3)若entry标记为non-Global.,请求进行地址翻译的ASID等于TLB entry的ASID

4) ....

3,进程切换和ASID(address space identifier)

进程有自己独立的VA,若TLB不标识VA,进程切换是,VA变化,TLB的entry也应该无效了要invalidate all,

但这么做从功能上没问题,性能却下降。

好的方案是区分global pages(内核地址空间)和process-specific pages,

Global pages,所有进程一样,进程切换后仍然需要这些entry,不用flush TLB,

Process-specific pages的TLB entry,一旦切换,TLB不能识别,就要flush掉上一个进程VA的TLB entry。

若支持ASID就不通了,TLB 的entry,保存多个相同的VA到不同的PA的映射也是可以的,只要他们有不同的ASID。

4,TLB的一致性问题,

TLB也是一种cache,有cache就意味着数据有多个copy,所以存在一致性coherence问题。

与数据,指令cahce或者unified cahche不同的是,硬件不维护TLB的coherence,一旦软件修改了page table,软件也要进程TLB invalidate操作,以维护TLB coherence。

5,TLB操作过程

四,TLB flush API

invalidate使无效

https://blog.csdn.net/qingfengjuechen/article/details/83749946

clean:对于回写类型的数据cache,若包含尚未写到主存的数据,则将数据写到主存

invalidate:将cache的某个块(或者所有)标识成无效,使所有访问这个块的操作一定是不命中。对于写回类型的数据cache来说,使无效,并不使数据写到主存中。(invalidate=flush)

猜你喜欢

转载自blog.csdn.net/u012654756/article/details/88815404
TLB