linux内核源码分析之页表缓存

Posted 为了维护世界和平_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux内核源码分析之页表缓存相关的知识,希望对你有一定的参考价值。

        处理器的内存单元(MMU)负责把虚拟地址转换成物理地址。为了改进虚拟地址到物理地址的转换速度,引入TLB的高速缓存。即页表缓存

        页表缓存用来缓存最近使用过的页表项,有些处理器使用两级页表缓存:第一级TLB分为指令TLB和数据TLB,第二级TLB是统一TLB,即指令和数据公用TLB

TLB管理

如果内核修改了缓存在TLB中的数据,那么旧的数据必须废除,内核如何保证一致性?

函数
flush_tlb_all使所有TLB失效
flush_tlb_mm使指定用户地址空间的所有TLB失效
flush_tlb_range使指定的地址空间范围的TLB失效
flush_tlb_page使指定用户地址空间里面的指定虚拟地址页的TLB表项失效
flush_tlb_kernel_range使内核虚拟地址范围的TLB表项失效
update_mmu_cache修改页表项后把页表项设置到页表缓存,由软件管理页表缓存的处理器必须实现此函数。
tlb_migrate_finish内核把进程从一个处理器迁移到另外一个处理器后,调用此函数以更新页表缓存或上下文特定信息。

当TLB没有命中的时候,ARM64处理器的内存管理单元自动遍历内存中的页表,把页表项复制到TLB,不需要软件把页表写到TLB,所以ARM64架构没有提供写TLB的指令。

#define isb()		asm volatile("isb" : : : "memory")
#define dmb(opt)	asm volatile("dmb " #opt : : : "memory")
#define dsb(opt)	asm volatile("dsb " #opt : : : "memory")
#define __TLBI_1(op, arg) asm ("tlbi " #op ", %0\\n"			       \\
		   ALTERNATIVE("nop\\n			nop",		       \\
			       "dsb ish\\n		tlbi " #op ", %0",     \\
			       ARM64_WORKAROUND_REPEAT_TLBI,		       \\
			       CONFIG_ARM64_WORKAROUND_REPEAT_TLBI)	       \\
			    : : "r" (arg))

#define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg)

#define __tlbi(op, ...)		__TLBI_N(op, ##__VA_ARGS__, 1, 0)

static inline void flush_tlb_all(void)

	dsb(ishst);
	__tlbi(vmalle1is);
	dsb(ish);
	isb();

 展开后的程序为

static inline void flush_tlb_all(void)

    //确保屏障前面的存储指令执行完,dsb是数据同步,ish表示共享域是内部共享,st表示存储
	asm volatile("dsb  ishst" : : : "memory");
    //使所有核匹配当前VMID,阶段1和异常级别1的所有TLB表项失效
	asm ("tlbi vmallelis" : :);
    //确保TLB前面指令执行完毕
    asm volatile("dsb  ish" : : : "memory");
    //指令同步屏障,指令冲刷处理器的流水线,重新读取屏障指令后面的所有指令
	asm volatile("isb" : : : "memory")

 local_flush_tlb_all用来使当前核的所有TLB表项失效

static inline void local_flush_tlb_all(void)

	dsb(nshst);
	__tlbi(vmalle1);
	dsb(nsh);
	isb();

和函数flush_tlb_all的区别如下

1)指令dsb中的ish换成了nsh,nsh是非共享,表示数据同步屏障指令仅在当前核起作用

2)指令tlbi没有携带is,表示仅仅使当前核的TLB表项失效。

地址空间标识

        为了减少在进程切换时清空页表缓存的需要,ARM64处理器的页表缓存使用非全局位区分内核和进程的页表项。使用地址空间标识符ASID(Address Space Identifier)区分不同进程的页表项。

虚拟机标识符

        虚拟机里面运行的客户操作系统的虚拟地址换成物理地址分两个阶段:第1阶段把虚拟 地址转换成中间物理地址,第2阶段把中间物理地址转换成物理地址。第1阶段转换由客户操作 系统的内存控制,和非虚拟化的转换过程相同。第2阶段转换由虚拟机监控器控制,虚拟机监 控器为每个虚拟机维护一个转换表,分配一个虚拟机标识符(Virtual Machine Identifier,VMID),寄存器VTTBR_EL2(虚拟化转换表基准寄存器,Virtualization Translation Table Base Register)存放当前虚拟机的阶段2转换表的物理地址。

参考链接

https://course.0voice.com/v1/course/intro?courseId=2&agentId=0


以上是关于linux内核源码分析之页表缓存的主要内容,如果未能解决你的问题,请参考以下文章

linux内核源码解析03–启动代码分析之主内核页表创建

Linux内核源码分析之《内存管理架构》

linux内核源码分析之内存屏障和RCU机制

Linux 内核 内存管理优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )

Linux 内核 内存管理内存管理架构 ③ ( Linux 内核中的内存管理模块 | 页分配器 | 不连续页分配器 | 内存控制组 | 硬件设备内存管理 | MMU | 页表缓存 | 高速缓存 )

Linux 内核 内存管理内存管理架构 ③ ( Linux 内核中的内存管理模块 | 页分配器 | 不连续页分配器 | 内存控制组 | 硬件设备内存管理 | MMU | 页表缓存 | 高速缓存 )