ARM架构中导致独占式内存访问Exclusive access 指令(LDXR/STXR)失败的原因分析

在之前的博文当中,笔者介绍了ARM中支持同步和信号量的硬件实现机制:Exclusive access(独占式访问)以及Load-Exclusive/Store-Exclusive指令的使用:
ARMv8 同步和信号量(Synchronization and semaphores)简介
ARMv8 同步和信号量(读写一致性问题):Load-Exclusive/Store-Exclusive指令详解
在Load-Exclusive/Store-Exclusive指令的使用过程中,存在着一些使用限制。如果未按照规范,错误地使用Load-Exclusive/Store-Exclusive指令,可能会造成Load-Exclusive/Store-Exclusive失效。对于Load-Exclusive指令,我们可以检查数据是否load成功;对于Store-Exclusive指令,会返回一个状态位信息,为0表示exclusive 访问成功,为 1 表示失败。
下面笔者将介绍Load-Exclusive/Store-Exclusive指令的一些使用限制、注意事项,以及当发生Load-Exclusive/Store-Exclusive访问内存失败时,我们应当如何分析和定位问题。

ARM架构中导致独占式内存访问Exclusive access 指令(LDXR/STXR)失败的原因分析

  • 一,LoadExcl/StoreExcl 指令应当成对使用
    • 1.1 LoadExcl 和 StoreExcl 应当使用同一个地址
    • 1.2 LoadExcl 和 StoreExcl 的transaction size和访问的寄存器数量应当保持一致
    • 1.3 LoadExcl 和 StoreExcl 访问地址空间的Tag Checked property和memory attribute应当一致
  • 二,在LoadExcl 和 StoreExcl指令对之间不应该出现的操作
  • 三,LoadExcl 和 StoreExcl指令注意事项
    • 3.1 LoadExcl 和 StoreExcl指令执行的先后时间差应该尽可能短
    • 3.2 Granule size建议使用保留值(Exclusives reservation granule)
    • 3.3 VA到PA的映射关系不应发生改变
    • 3.4 发生cache line eviction或者是cache 维护指令(clean、invalidate、clean&invalidate)
    • 3.5 使用预加载指令预取数据 Prefetch memory
    • 3.6 异常产生、异常返回ERET以及debug state切换
  • 五,当Exclusive Access失败时应当如何分析
    • 1 检查访问的内存属性:shareability 、cacheability
    • 2 检查 local monitor 和 global monitor
      • 2.1 local monitor
      • 2.2 Global monitor 的具体实现

一,LoadExcl/StoreExcl 指令应当成对使用

在这里插入图片描述
如上表所示,为ARMv8架构提供Exclusive Access的A64相关指令。LoadExcl/StoreExcl 指令应当成对使用有两层含义,其中一个就是:Exclusive 访问时,load exclusive 和 store exclusive的指令应该按照上表所述,配对使用。比如当使用LDXR指令进行load exclusive access时,对应的,应当使用STXR执行store exclusive access。
不仅如此,LoadExcl/StoreExcl 指令访问的地址空间也应当相同,需遵循如下原则:

1.1 LoadExcl 和 StoreExcl 应当使用同一个地址

如果开了MMU,则LoadExcl 和 StoreExcl 指令应当访问同一个虚拟地址(VA)。如果没有使能MMU,则应当访问同一个物理地址(PA)。

1.2 LoadExcl 和 StoreExcl 的transaction size和访问的寄存器数量应当保持一致

如上表所示,不同的LoadExcl 和 StoreExcl访问内存的transaction size和访问的寄存器数量都不同,为了确保LoadExcl 和 StoreExcl 的transaction size和访问的寄存器数量保持一致,应当按照上表规则,配对使用。

1.3 LoadExcl 和 StoreExcl 访问地址空间的Tag Checked property和memory attribute应当一致

在LoadExcl 和 StoreExcl 访问同一个内存地址的时候,如果该内存空间的Tag Checked property或者内存属性发生了变化,将会导致不可预测的后果:exclusive 访问极大可能会失败。常见的内存属性比如有 shareability (inner shareable,outer shareable和non-shareable)和Cacheability (write-back和write-through)。

二,在LoadExcl 和 StoreExcl指令对之间不应该出现的操作

在LoadExcl 和 StoreExcl指令对之间,以下操作不应出现:

  • 显式的内存影响
  • 内存预加载
  • 直接或间接的系统寄存器读写
  • 地址转换指令
  • cache 或者TLB 维护指令
  • 异常产生指令
  • Data abort 异常
  • 异常返回
  • ISB 内存屏障指令
  • 间接的分支跳转指令

如下示例代码,为使用ldxr和stxr指令进行原子自加1的示例程序:

; extern int atom_add(int *val);
_atom_add:
mov x9, x0 ; 备份 x0,为了失败时恢复,x9=x0=*val
ldxr w0, [x9] ; 从val所在的内存中读取一个 int,并标记 Exclusive
add w0, w0, #1 ; w0=w0+1
stxr w8, w0, [x9] ; 尝试写回 val 位置,写入结果保存在 w8
cbz w8, atom_add_done ; 如果 w8 为 0 说明成功,跳到程序结束
mov x0, x9 ; 恢复备份的 x0,重新执行 atom_add
b _atom_add
atom_add_done:
ret

在多线程或者多核的系统中,复杂的环境无法保证每次的exclusive access都能成功,所以在使用exclusive access指令时,建议养成一个良好的编程习惯:在store exclusive 指令执行后,检查其返回的状态标志(为0表示exclusive访问成功,为1表示失败)。如果访问成功,程序继续往下执行,如果失败则跳转到load exclusive指令的地址,重新进行 load/store exclusive操作。
如果store-exclusive返回一个失败的结果,在返回结果并从新开始新的load-exclusive指令之间,不应当进行如下操作:

  • 不允许有任何的load/ store指令或者PRFM指令访问当前exclusive 维护的granule中的地址,即使该地址与即将执行的load-exclusive指令访问的地址不同,但是处于同一个granule,也同样不行。
  • 期间没有直接或者间接的系统寄存器写入,地址转换指令,cache或者TLB维护指令,异常产生,异常返回或者间接的分支跳转。
  • 对一块连续的内存空间进行任何的load 或者store操作时,不能超过 512 bytes。

三,LoadExcl 和 StoreExcl指令注意事项

3.1 LoadExcl 和 StoreExcl指令执行的先后时间差应该尽可能短

在Exclusive access的实际应用中,应当尽量缩短Load exclusive 指令和 Store exclusive指令之间的距离,最好在单线程内将LoadExcl 和 StoreExcl指令都执行完成。换句话说,执行完load exclusive指令后,在尽可能短的时间内执行store exclusive指令,完成一对load exclusive和store exclusive指令。Load exclusive 指令和 Store exclusive指令之间,尽量减小Exclusive monitor的状态机被意外因素重置的可能性。此外,考虑到最佳的性能要求,ARM官方强烈建议,在一个单线程的执行过程中,LoadExclusive和Store Exclusive之间的指令数量最好不要超过128 bytes。

3.2 Granule size建议使用保留值(Exclusives reservation granule)

ARM架构支持最大2048 bytes的granule size,作为Exclusives reservation granule。
什么是Exclusives reservation granule?
当执行一个Load-Exclusive指令时,将会忽略64位地址的最低有效位,同时标记一个大小为 2^a byte大小的内存空间为Exclusive Access状态。被标记的地址可以是该内存块的任意一个地址。这个内存块称为 独占式保留颗粒(Exclusives reservation granule),granule的大小范围在4到512个words(1 word = 4 bytes)之间,其具体的大小由具体的架构实现定义。比如在A53处理器中,granule的大小为一个cache line的大小:16 words(16 words = 64 bytes = 512 bits)。

  • 4 words in an implementation where a is 4.
  • 512 words in an implementation where a is 11.
    当a为4时,granule的大小为 4个words,比如对 0x341B4这个地址执行 LDXRB 指令,将会把 0x341B0 到 0x341BF这块内存空间标记为exclusive access。
    关于Exclusives reservation granule size的默认值,可以在CTR(Cache Type Register)寄存中找到该字段,比如CTR_EL0[23:20] ==0b0100 = 4,则2^4 = 16 words = 64 bytes。
    在这里插入图片描述
    在这里插入图片描述

3.3 VA到PA的映射关系不应发生改变

如果在执行LoadExcl 和 StoreExcl指令期间,使用 break-before-make 方式更新了VA到PA的映射关系。在旧的页表(映射关系)失效后,如果有两个store exclusive指令先后对同一个PA进行写操作,后一个的store exclusive指令可能会失败。

3.4 发生cache line eviction或者是cache 维护指令(clean、invalidate、clean&invalidate)

无论是cache clean、invalidate还是clean&invalidate操作,都会对local monitor和global monitor的Exclusive Access状态造成不可预测的影响。cache 维护指令可能会重置monitor的状态机,或者也可能保持它的exclusive access状态。此外,对于基与地址的缓存维护指令,如果该地址是shreable的,那么位于该shareability domain的其他处理器,若也正在维护该地址的exclusive access,那么也会影响到其他处理器相关的monitor的状态。

如果在load exclusive指令和store exclusive 指令有普通的store指令,普通的store指令的操作地址无论是当前Load exclusive指令标记的地址还是其他地址,都不会对local monitor的状态机有直接的影响,如下图所示:
在这里插入图片描述
但是,如果访问的地址空间的内存属性为cacheable的,该普通的store操作造成了被标记exclusive access的地址所在的cache line 发生了eviction,cache line的eviction会导致monitor的状态机被重置。因此,ARM建议在load exclusive和store exclusive指令之间,最好不要有任何的load 或者store操作,因为这些额外的读写指令有可能导致被标记地址所在的cache line被evict。而任何缓存维护指令和cache line eviction操作,都会重置 exclusive monitor的状态机。

3.5 使用预加载指令预取数据 Prefetch memory

如下示例程序,在Load exclusive指令之前,使用了PREM 指令提前将要Load exclusive access的数据存到cache中:

; extern int atom_add(int *val);
_atom_add:
PRFM PSTL1KEEP, x0 ; 使用预加载指令将x0指向的地址上的数据预加载到cache中
mov x9, x0 ; 备份 x0,为了失败时恢复,x9=x0=*val
ldxr w0, [x9] ; 从val所在的内存中读取一个 int,并标记 Exclusive
add w0, w0, #1 ; w0=w0+1
stxr w8, w0, [x9] ; 尝试写回 val 位置,写入结果保存在 w8
cbz w8, atom_add_done ; 如果 w8 为 0 说明成功,跳到程序结束
mov x0, x9 ; 恢复备份的 x0,重新执行 atom_add
b _atom_add
atom_add_done:
ret

这样做有两大风险:

  1. 不能确保PRFM指令已经将数据预加载到cache中后,才执行ldxr指令。可能导致ldxr指令执行失败,未进入 exclusive access状态,如果非要执行PRFM指令,建议在PRFM指令后加上DMB内存屏障,确保预加载完成后再执行ldxr。
  2. 如果多个core同时对同一个地址执行 PFRM PST* 指令,可能会导致Exclusive access状态的丢失。这意味着如果多个core在高频率地对同一个地址执行PFRM PST* 指令,可能会阻碍其他core的正常执行。

3.6 异常产生、异常返回ERET以及debug state切换

如果在LoadExcl 和 StoreExcl指令指令之间产生了异常或者是异常返回(ERET),不管是同步异常还是异步异常(中断或者SError),都有可能导致Exclusive monitor的状态丢失,导致store exclusive指令执行失败。
不仅如此,外部的一些debug 事件(external debug event)会导致处理器进入debug state,在debug state和正常状态之间切换,也会导致Exclusive monitor的状态丢失。常见的debug event有:

  • External debug request debug event
  • Halt instruction debug event
  • Halting step debug event
  • Exception catch debug event
  • Reset catch debug event
  • Software access debug event
  • OS unlock catch debug event
  • Breakpoint event
  • Watchpoint event

五,当Exclusive Access失败时应当如何分析

如下图所示,为ARM架构下的exclusive access monitor的一般架构图,其中local monitor位于每个core的L1 内存系统中,并且如果实现了global monitor的话,它一般位于外部内存的内存接口中,针对不同的内存有着不同的global monitor。
Exclusive access失败(load exclusive失败或者store exclusive 失败)的根本原因就是 exclusive monitor中的状态机的状态切换(open状态转exclusive状态,或者exclusive状态转换到open状态)没有按照预期的效果进行。有可能是Exclusive monitor的状态机被清除了,或者是Exclusive monitor没有收到来自内存系统的正确的反馈(ACK),导致状态机切换到错误状态。
接下来,笔者将介绍当遇到exclusive access失败时的一般分析方法。
在这里插入图片描述

1 检查访问的内存属性:shareability 、cacheability

首先我们要确定是否使用到了local monitor和 global monitor,而内存属性中的shareability和cacheability 会影响到local monitor 和global monitor的使用。如果exclusive access访问的目标地址的shareability为non-shareable的,并且是单个处理器中的程序发起的,则使用local monitor。但是local monitor同样也会使用在inner shareable的地址空间,比如在多core多线程的环境中,local monitor和global monitor共同维护exclusive access的操作。如果是non-cacheable的地址空间,系统默认会把non-cacheable当做是outer-shareable,所以也需要local monitor和global monitor。

2 检查 local monitor 和 global monitor

其次,检查当前架构下的local monitor和global monitor的具体实现。

2.1 local monitor

如下图所示为ARMv8 Cortex-A系统下的local monitor的状态机转换图,其中打星号的操作由具体的架构实现来决定
在这里插入图片描述

而下图则是Cortex-A55处理器的local monitor的具体实现,在执行完LoadExcl(x)后,无论是对当前被标记地址进行普通的store指令还是对其他地址进行普通的store指令,都不会对当前的 Exclusive access产生任何影响。
在这里插入图片描述

2.2 Global monitor 的具体实现

其次,我们还要检查当前系统下的Global monitor的具体实现:

  • 对不同memory访问时,是否实现了不同的Global monitor。
  • Global monitor位于哪里,位于内存接口还是系统总线上。
  • Global monitor最多执行维护多少个状态机,最多同时支持多少个不同地址的exclusive access 操作。
  • 有何依赖,是否依赖于系统总线上的ack。比如CHI总线的Exclusive access,需要下级总线回应Exclusive Okay或者Normal Okay。如果处理器发出的transaction 为 Exclusive access,但是系统总线上返回的是Normal Okay,那么会导致该Exclusive access 失败。
  • 总线上是否有针对exclusive access的特殊配置,或者能够使能或者禁止Exclusive access的配置。
  • Global Monitor的具体实现,如下图所示,Global monitor的很多操作(如下打星号的操作)都依赖于具体的系统实现:
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/750814.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7.Java整合MongoDB—项目创建

整合MongoDB MongoDB的基本知识有所了解之后,我们开始着手上代码了,进来先来项目创建,如何引入mongodb,以及测试一下能否连接数据库。 1 新建springboot项目 其实只需要spring boot mongodb这个依赖就行,加那么多纯属…

【TB作品】MSP430,波形发生器,单片机,Proteus仿真

文章目录 题目效果梯形波100个点产生方法锯齿波100个点产生方法c代码和proteus仿真 题目 114 波形发生器的制作 设计要求 设计一个能产生正弦波、方波、三角波、梯形波、锯齿波的波形发生器。设置5个开关K1~K5(从 上到下),分别对应正弦波、方波、三角波、梯形波、锯齿波,按一下…

短剧分销怎么赚钱的?保姆级教程助你短剧cps推广赚大钱

短剧分销怎么赚钱的?小白也能月入过万/“蜂小推“保姆级教程,助你短剧分销赚大钱! 相信大家或多或少都在某些群里看到一些“霸道总裁爱上职场小菜鸟...”“这类链接,无利不起早,为什么会有那么多在群里分享这些狗血视…

Pycharm连接远程服务器Anoconda中的虚拟环境

在配置远程解释器时,踩过一些坑,现在记录一下配置过程: 步骤1: 打开pycharm的File里面的Settings 里面的Project:你的项目名称目录下的Python Interpreter。 步骤二: 点击右上角的“add interpreter”,选择…

Tomcat内存马

Tomcat内存马 前言 描述Servlet3.0后允许动态注册组件 这一技术的实现有赖于官方对Servlet3.0的升级,Servlet在3.0版本之后能够支持动态注册组件。 而Tomcat直到7.x才支持Servlet3.0,因此通过动态添加恶意组件注入内存马的方式适合Tomcat7.x及以上。…

【AI+编程】利用chatGPT编写python程序处理日常excel工作提升效率小技巧

之前写过一篇AI编程相关的文章 【人工智能】为啥我最近很少写python编程文章了,浅谈AI编程RPA提升工作效率 。 最近有同学私信我,怎么利用AI编程来提升工作效率,除了文章里讲的 使用AI帮忙写算法、代码提示、代码优化、不同语言转换(如J…

Axios异步框架和Json数据格式

一.Axios异步框架 对原生的Ajax进行封装,简化书写。 给大家提供一下axios的源码: 链接:https://pan.baidu.com/s/1ZSrUBe0B4dIq7d6NpUzqOQ 提取码:gr86 将源码粘贴到项目之中。 1.基础使用 首先单独创建一个Servlet&#xf…

Godot 学习笔记(2):信号深入讲解

文章目录 前言相关链接环境信号简单项目搭建默认的信号先在label里面预制接收函数添加信号 自定义无参数信号为了做区分,我们在label新增一个函数 自定义带参数信号Button代码label代码连接信号 自定义复杂参数信号自定义GodotObject类ButtonLabel连接信号 信号函数…

数字IC实践项目(9)—SNN加速器的设计和实现(tiny_ODIN)

数字IC实践项目(9)—基于Verilog的SNN加速器 写在前面的话项目整体框图完整电路框图 项目简介和学习目的软件环境要求 Wave&CoverageTiming,Area & Power总结 写在前面的话 项目介绍: SNN硬件加速器是一种专为脉冲神经网…

uniapp样式穿透修改uview的按钮button图标

需求&#xff1a; 想给按钮icon和text改字体颜色&#xff0c;结果发现图标颜色并没有改变 .u-button{width: 300rpx;background-color: aliceblue;color: #aaaa7f;margin-top: 20rpx; }接下来用样式穿透解决 1、首先&#xff0c;给UI组件包裹一层view <view class"t…

ElasticSearch:数据的魔法世界

​ 欢迎来到ElasticSearch的奇妙之旅&#xff01;在这个充满魔法的搜索引擎世界中&#xff0c;数据不再是沉闷的数字和字母&#xff0c;而是变得充满活力和灵动。无论你是刚刚踏入数据探索的小白&#xff0c;还是已经对搜索引擎有所了解的行者&#xff0c;本篇博客都将为你揭示…

unity内存优化之AB包篇(微信小游戏)

1.搭建资源服务器使用(HFS软件(https://www.pianshen.com/article/54621708008/)) using System.Collections; using System.Collections.Generic; using UnityEngine;using System;public class Singleton<T> where T : class, new() {private static readonly Lazy<…

【集成开发环境】-VS Code:C/C++ 环境配置

简介 VS Code&#xff0c;全称Visual Studio Code&#xff0c;是一款由微软开发的跨平台源代码编辑器。它支持Windows、Linux和macOS等操作系统&#xff0c;并且具有轻量级、高效、可扩展等特点&#xff0c;深受广大开发者的喜爱。 VS Code拥有丰富的功能特性&#xff0c;包括…

计算机三级网络技术综合题第三题、第四题详细解析

第三大题 DHCP报文分析&#xff08;10分&#xff09; 一、DHCP工作流程&#xff08;一般情况下&#xff09; 报文摘要 对应上面报文1—4 报文1、3DHCP&#xff1a;Request&#xff1b; 报文2、4DHCP&#xff1a;Reply。 例题&#xff08;第三套&#xff09;&#xff1a;在一…

程序员入行忠告!

点击下方“JavaEdge”&#xff0c;选择“设为星标” 第一时间关注技术干货&#xff01; 关注我&#xff0c;紧跟本系列专栏文章&#xff0c;咱们下篇再续&#xff01; 作者简介&#xff1a;魔都技术专家兼架构&#xff0c;多家大厂后端一线研发经验&#xff0c;各大技术社区头部…

十五、自回归(AutoRegressive)和自编码(AutoEncoding)语言模型

参考自回归语言模型&#xff08;AR&#xff09;和自编码语言模型&#xff08;AE&#xff09; 1 自回归语言模型&#xff08; AR&#xff09; 自回归语言模型&#xff08;AR&#xff09;就是根据上文内容&#xff08;或下文内容&#xff09;预测下一个&#xff08;或前一个&…

安装OpenEBS,镜像总是报错ImagePullBackOff或者ErrImagePull的解决方法

按照 KubeSphere 官方文档安装 OpenEBS&#xff0c;镜像总是报错ImagePullBackOff或者ErrImagePull的解决方法 helm 有很多更换 源 的文章&#xff0c;有一些是写更换阿里云的源&#xff0c;但是阿里云的源根本没更新OpenEBS的镜像。 在网上找到1个可用的源&#xff1a; 可用的…

探讨TCP的可靠性以及三次握手的奥秘

&#x1f31f; 欢迎来到 我的博客&#xff01; &#x1f308; &#x1f4a1; 探索未知, 分享知识 !&#x1f4ab; 本文目录 1. TCP的可靠性机制1.2可靠性的基础上,尽可能得提高效率 2. TCP三次握手过程3. 为何不是四次握手&#xff1f; 在互联网的复杂世界中&#xff0c;TCP&am…

基于springboot的高校教师教研信息填报系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

亚马逊云科技Glue

Glue 最重要的部分&#xff0c; ETL&#xff1a;用于从 A 点&#xff08;我们的源数据&#xff09;提取、转换和加载数据到 B 点&#xff08;目标文件或数据存储库&#xff09;。 AWS Glue 会为您执行大量此类工作。 转换通常是更繁重的工作&#xff0c;需要从各种来源进行组合…