memory-barriers.txt « Documentation - kernel/git/torvalds/linux.git - Linux kernel source tree
目录
Instruction Synchronization Barrier (ISB)
Data Memory Barrier (DMB)
Data Synchronization Barrier (DSB)
指令参数
总结
ARM体系结构包括屏障指令,用于在特定点强制访问顺序和访问完成。在某些体系结构中,类似的指令称为fence。
在此架构中,有三条屏障指令:
Instruction Synchronization Barrier (ISB)Data Memory Barrier (DMB)Data Synchronization Barrier (DSB)Instruction Synchronization Barrier (ISB)指令同步屏障(ISB)
这是用来保证任何后续的指令都会再次被获取(指令流水线被刷新),以便使用当前的MMU配置检查特权和访问权限。它用于确保任何先前执行的上下文更改操作(如对系统控制寄存器的写入)在ISB完成时已经完成。
例如,在硬件方面,这可能意味着指令流水线被刷新。它的典型用途是内存管理、缓存控制和上下文切换代码,或者在内存中移动代码。
ARMv8体系结构将上下文定义为系统寄存器的状态,并将上下文更改操作定义为缓存、TLB和分支预测器维护操作,或对系统控制寄存器的更改,例如SCTLR_EL1、TCR_EL1和TTBRn_EL1。这种上下文更改操作的效果只能保证在上下文同步事件之后才能看到。
有三种上下文同步事件:
异常发生
从异常返回
Instruction Synchronization Barrier (ISB).
ISB刷新流水线,并从缓存或内存中重新获取指令,并确保ISB之前完成的任何上下文更改操作的效果对ISB之后的任何指令都可见。
它还确保在ISB指令之后的任何上下文更改操作只在ISB执行之后生效,并且ISB之前的指令看不到这些操作。
这并不意味着在每个修改处理器寄存器的指令之后都需要ISB。例如,对PSTATE字段、ELR、SP和SPSR的读取或写入,按程序顺序相对于其他指令进行。
此示例显示如何启用浮点单元和NEON,您可以在AArch64中通过写入CPACR_EL1寄存器的位[20]来实现这一点。ISB是一个上下文同步事件,它保证在执行任何后续或NEON指令之前完成enable。
MRS X1, CPACR_EL1
ORR X1, X1, #(0x3 << 20)
MSR CPACR_EL1, X1
ISB
Data Memory Barrier (DMB)这可以防止跨屏障指令对数据访问指令进行重新排序。在DMB之后的任何数据访问之前,该处理器在DMB之前执行的所有数据访问(即加载或存储,而不是指令获取)对指定共享域中的所有其他主控机可见。
它可确保会先检测到程序中位于DMB指令前的所有内存访问指令,然后再检测到程序中位于DMB指令后的显式内存访问指令。它不影响其它指令在处理器上的执行顺序。
如上述指令,在LDR加载指令之后执行了DMB,由于DMB指令只对内存访问指令有效,所以ADD指令可以在LDR之前或者之后执行,但是STR指令会受到影响,它必须在LDR指令执行完毕后,才会执行STR。
它还确保在执行任何后续数据访问之前,任何显式的先前数据缓存(data cache)或统一缓存(unified cache)维护操作都已完成。
如上述指令,在缓存维护指令DC之后执行了LDR指令,LDR指令可能在DC指令执行完毕之前或者之后执行。但是在DMB指令之后的LDR,一定是在DMB之前的DC和LDR指令执行完毕后,再执行。
Data Synchronization Barrier (DSB)此指令的强制执行顺序与DMB,但具有阻止执行任何进一步指令的附加效果,而不仅仅是加载或存储,或两者兼而有之,直到同步完成。这可以用来阻止SEV指令的执行,例如,SEV指令会向其他内核发出发生事件的信号。它将等待此处理器发出的所有缓存、TLB和分支预测器维护操作完成,以用于指定的可共享性域。
如上述指令,如果是DMB,最后的ADD不会受影响,但是DSB会影响任何进一步需要执行的指令。ADD必须在DC和STR指令执行完成后才会执行。
只有当此指令执行完毕后,才会执行程序中位于此指令后的指令。
当满足以下条件时,此指令才会完成:
位于此指令前的所有显示内存访问均完成。
位于此指令前的所有缓存、跳转预测和TLB维护操作全部完成。
指令参数有序访问字段指定屏障操作的访问类别。有三种选择:
Load - Load/Store这意味着屏障需要在屏障之前完成所有load,但不需要完成store。在程序顺序中出现在屏障之后的加载和存储都必须等待屏障完成。
Store - Store这意味着屏障只影响存储访问,负载仍然可以围绕屏障自由重新排序。
Any - Any这意味着装载和存储必须在屏障之前完成。在程序顺序中出现在屏障之后的加载和存储都必须等待屏障完成。
总结屏障用于防止发生不安全的优化,并强制执行特定的内存顺序。因此,使用不必要的屏障指令会降低软件性能。
执行顺序的规则的一个更微妙的影响是,内核的指令接口、数据接口和MMU表遍历器被视为独立的观察者。例如,这意味着您可能需要使用DSB指令来确保一个接口的访问在另一个接口上是可观察的
如果执行数据缓存清除和失效指令,例如DC CVAU、X0,则必须在此之后插入DSB指令,以确保后续页表遍历、对转换表条目的修改、指令获取或对内存中指令的更新都可以看到新值。
DSB被要求确保维护操作完成,ISB被要求确保这些操作的效果可以通过下面的说明看到。
处理器可能会在任何时候推测性地访问标记为正常的地址。因此,在考虑是否需要障碍时,不要只考虑由加载或存储指令生成的显式访问。
AArch64使用隐式屏障语义添加了新的加载和存储指令。这些要求隐式屏障前后的所有加载和存储都按程序顺序进行观察。