AR# 47586

Zynq-7000 SoC, APU - 对终止存储器区域的预测性缓存读取清除了内部独占监控,会导致活锁

描述

当可高速缓存读取收到外部终止信息时,被终止行在数据高速缓存中就将被指定为无效,数据高速缓存中的任何分配都可清空内部独占监控器。 因此,如果一个程序执行一个包含 DSB 指令的 LDREX/STREX 环路,并且在不断接收 LDREX/STREX 序列中间的终止答复,那么 LDREX/STREX 就无法成功执行。

在那些可能会在答复可高速缓存存储器请求过程中生成外部终止的系统中,会发生这种问题。有两种解决方法:打开分支预测或移除 LDREX/STREX 序列中间的 DSB。

解决方案

影响:

较小

解决方法::

打开分支预测或移除 LDREX/STREX 序列中间的 DSB。

受影响的配置:

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

受影响的器件修订版本:全部,无计划修复。请参考(Xilinx 答复 47916) - Zynq-7000 SoC 芯片修订版差异。



在 Cortex-A9 上当可高速缓存读取收到外部终止信息时,被终止行在数据高速缓存中就将被指定为无效,数据高速缓存中的任何分配都可清空内部独占监控器。 然而,如果一个程序所执行的 LDREX/STREX 环路在不断接收 LDREX/STREX 序列中间的终止答复信息,那么 LDREX/STREX 序列就无法成功执行,导致处理器活锁。

以下代码序列实例可说明这个问题:

loop LDREX ... DSB STREX CMP BNE loop ... LDR (进入终止区)

LDREX/STREX 在首次通过环路时未成功执行,但可预测 BNE,因此随后的 LDR 会以预测方式执行,而处理器则在不断执行:

LDR 指令,终止区域(该预测的 LDR 现在出现在 LDREX & DSB“之前”)LDREX DSB STREX

LDR 在 L1 高速缓存中漏掉,由于其正在进行终止,因此无法得到有效分配。

执行 LDREX,并设置独占监控器。

执行 DSB 。等到 LDR 执行完毕,其就可终止,从而可在数据高速缓存中分配为“无效”,这样可清空独占监控器。接着执行 STREX,但由于此时独占监控器已被清空,因此 STREX 执行会失败。

由于可能会再次预测 BNE ,因此 LDR 会再次以预测方式执行,而代码环路则回到相同的失败 LDREX/STREX 序列上。

影响详情

在那些可能会在答复可高速缓存存储器请求过程中生成外部终止的系统中,会发生这种问题。如果程序达到稳定状态,其中内部独占监控器在 LDREX/STREX 序列中间不断被清空,那么处理器就会产生活锁。

由于存在几个条件可防止这种错误发生,因此在实际中这种情况的发生几率似乎很小

  • 普通 LDREX/STREX 代码序列不包含任何 DSB,因此在每次迭代中系统在 LDREX/STREX 序列正中间返回终止答复的可能性非常小
  • 会发生一些外部刺激(例如中断),导致可使处理器退出活锁状态的时序发生变化。
  • 分支预测启用频率非常高,因此环路内最后的分支通常会在几次环路迭代后被正确预测,这样可防止发布预测的 LDR,使 LDREX/STREX 的下次迭代成功执行。

解决方法详情

此问题有2个解决方案:

  • 打开分支预测。
  • 移除 LDREX/STREX 序列中间的 DSB。如果确实需要 DSB ,那么强烈推荐将其放在 LDREX/STREX 序列之前,并通过 ARM 架构执行 LDREX/STREX 序列。

链接问答记录

主要问答记录

Answer Number 问答标题 问题版本 已解决问题的版本
47916 Zynq-7000 SoC 器件:芯片修订差异 N/A N/A
AR# 47586
日期 05/25/2018
状态 Active
Type 设计咨询
器件