Zynq-7000 SoC,APU - 可能无法确保对同一存储器位置的读取访问顺序

描述

在SMP环境中运行的处理器可以通过对相同存储器位置的后续读访问来绕过读访问。只有对标记为正常内存回写共享的内存区域的读访问才会出现此问题。

这并不常见,有多种解决方法。

影响:

次要。有多种解决方法。

变通办法:

绝大多数多处理代码不是以暴露问题的风格编写的。因此,预计该问题将影响依赖于此读取排序行为的非常特定的代码区域。有关更多信息,请参阅解决方法详细信息。

受影响的配置:

使用一个或两个处理器的系统。

受影响的器件版本: 所有。没有计划修复。请参阅(Xilinx答复47916) - Zynq-7000 SoC芯片版本差异。

ARM体系结构和一致性的一般规则要求按顺序读取到相同的存储器位置。由于一些内部重放路径机制,处理器可以看到通过对相同存储器位置的后续读访问绕过的读访问,因此不按程序顺序观察值。

该问题只能发生在SMP模式下的处理器上,标记为Normal Memory Write-Back Shared的内存区域。

解决方法细节

  • 在需要严格读取顺序的易失性存储器中使用LDREX指令而不是标准LDR。
  • 在受影响的LDR之间插入DMB指令,这需要这个严格的排序规则。这是工具链集成的推荐解决方法。

没有DMB屏障指令的序列

使用DMB屏障指令进行排序

结果是处理器2偶尔会错误地观察到Rx == <valueB>和Ry == <valueA>。

数据顺序保留。

在处理器1上

在处理器1上

STR <valueA>,[loc]

STR <valueA>,[loc]

STR <valueB>,[loc]

STR <valueB>,[loc]

在处理器2上

在处理器2上

LDR Rx,[loc]

LDR Rx,[loc]

DMB

LDR Ry,[loc]

LDR Ry,[loc]

DMB

除LDREX,LDREXB,LDREXH和LDREXD外,该问题可能会影响所有形式的存储器加载指令。

对于高级语言,编译器通常会优化或重新排序对同一存储器位置的多次访问,因此只有被声明为volatile的存储器位置才能被认为容易受到此问题的影响。此外,两个负载之间的任何屏障操作都足以防止触发问题的条件,因此只有无锁编程方法会受到影响。

注意:除非访问正常内存,否则使用LDREX是不可预测的,因此第二个序列不能用作访问内存中所有易失性对象的一般解决方法。

编辑 重设标签(回车键确认) 标为违禁 关闭 合并 删除

提问于 2018-07-31 14:49:29 +0800

这个帖子被标记为一个社区wiki

这个帖子是一个wiki(维基). 任何一个积分 >500的人都可以完善它