Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aarch64体系结构与编程13--原子操作与内存独占访问 #59

Open
jason--liu opened this issue Mar 10, 2021 · 0 comments
Open
Labels

Comments

@jason--liu
Copy link
Owner

jason--liu commented Mar 10, 2021

Linux内核提供的原子操作API接口函数

  • Linux内核提供了atomic_t类型的原子变量,它的实现依赖于不同的架构
  • atomic_t类型的原子操作函数可以保证了一个操作的原子性和完整性
  • “读-修改-回写”机制
    • 读取原子变量的值 到 通用寄存器中
    • 在通用寄存器里 修改原子变量的值
    • 把新值写回内存中
  • 基本原子操作函数

image
image
image

ARMv8对原子操作的支持

ARMv8对原子操作的支持

  • 第一种:传统的Load-exclusive和store-exclusive方式
    • 在ARMv8上都支持
    • LL/SC (Load-link/store-conditional)
  • 第二种:LSE(Large System Extensions)支持原子操作指令
    • 在ARMv8.1上开始支持,ARMv8.1-LSE
    • 新增Compare and Swap instructions
    • 新增Atomic memory operation instructions
    • 新增Swap instruction

image

传统的Load-exclusive和store-exclusive指令

Load-exclusive和store-exclusive指令

  • ldxr指令 :内存独占加载指令。从内存中以独占的方式加载内存地址的值到通用寄存器里
    ldxr {xt} , [xn | sp]
  • stxr指令 :内存独占存储指令。以独占的方式把新的数据存储到内存中
    stxr {ws}, {xt}, [xn | sp]
  • Load / Store Exclusive Pair指令
    LDXP {Xt1}, {Xt2}, [Xn|SP]
    STXP {Ws}, {Xt1}, {Xt2}, [Xn|SP]
  • 带acquire和release屏障原语的Load / Store Exclusive指令

独占监视器(Exclusive Monitor)

  • 独占监视器一共有两个状态:开放访问状态(Open Access state)和独占访问状态(Exclusive Access state)
  • ldxr指令从内存加载数据时,CPU会把这个内存地址标记为独占访问状态
  • 当CPU执行stxr指令的时候,需要根据独占监视器的状态来做决定
    • 如果独占监视器的状态为独占访问状态, 那么stxr指令存储成功,stxr指令返回0,独占监视器的状态变成了开放访问状态
    • 如果独占监视器的状态为开发访问状态, 那么stxr指令存储失败,stxr指令返回1

image

独占监视器注意事项

  • 独占监视器本身不是用来阻止CPU核心来访问被标记的内存,不会lock总线
  • 独占监视器 仅仅是起到监视的作用,监视状态的变化
  • 不能把 独占监视器看成是一个硬件的锁

image

独占监视器的组成架构

通常一个系统由多级独占监视器组成(由芯片设计时定义)

  • 本地独占监视器(Local monitor),适用于非共享(Non-shareable)的内存
  • 缓存一致性的全局独占监视器(Internal coherent globalmonitor),适用于普通类型的内存
  • 外部的全局独占监视器(External global monitor),适用于设备类型的内存

image

  • 有的SoC不支持 外部的全局独占监视器。例如树莓派4b上使用的BMC2711
  • 在MMU没有使能的情况下,我们访问物理内存变成了访问设备类型的内存,此时,使用ldxr和stxr指令会产生不可预测的错误。

image

  • 第8节课里提到 ldxr指令的大坑

ldxr指令的使用会有很多限制

  1. 首先确保访问的内存是 normal memory并且是 sharable的
    image
  2. 如果访问device memory,例如MMU没有打开的情况,那就需要CPU IP核心支持以独占方式访问device memory,这个需要查询 具体CPU IP手册的描述。例如:第6.4.5章
    image

独占监视器的粒度(Granularity of Exclusive Monitor)

  • CTR_EL1寄存器中的ERG(Exclusives Reservation Granule)定义了独占监视器监视的最小单位
  • ERG可以定义的范围是4words ~ 512words,不过通常是一个cache line的大小
  • 例如,假设ERG是2^4,即16字节。当使用ldrxb指令对0x341B4地址进行独占地读操作,那么从0x341b0~ 0x341bf都会标记为exclusive access

案例,简单锁实现

image
image
image
image
image
image
image

WFE指令在锁实现中的应用

  • 如果CPU0获取了锁,CPUn在spin等待锁的时候,让CPU进入低功耗模式,那么能节省功耗和提升性能
  • 获取锁的示例代码

image

  • 释放锁的示例代码
    image

WFE唤醒

通过WFE睡眠的CPU,下面方式唤醒

  • unmasked interrupt
  • Event(唤醒事情)

触发唤醒事件的方式

  • 执行了sev指令
  • 本地CPU执行了sevl指令
  • clear独占监视器,从独占状态变成开放状态

当持有锁的CPU通过stlr指令写入lock区域释放锁的时候,会触发一个唤醒事件,正在睡眠等待spinlock的CPU会被唤醒
image

原子内存访问操作(Atomic Memory Accesses)

ARMv8.1上支持下面三种原子内存访问操作( Large System Extensions)

  • Compare and Swap instructions, CAS and CASP
  • Atomic memory operation instructions
  • Swap instruction

通过ID_AA64ISAR0_EL1寄存器中的atomic域来判断是否支持LSE

比较并交换(Compare and Swap)指令

image
image

image

原子内存操作指令

image
image
image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant