来源:Linux阅码场, 罗玉平原创,欢迎投稿原创文章(要求投稿前未在任何平台发表),稿费500元人民币。投稿邮箱:21cnbao@gmail.com
作者简介:
罗玉平, IT行业工作近20年,先后从事无线通讯,linux平台和firmware开发多年,目前从事ARMv8-A架构和CPU软件的客户支持和培训工作。
引子
前文宝华的《宋宝华:关于ARM Linux原子操作的实现》谈到软件如何使用ARM V7之后的LDREX和STREX指令来实现spin lock和atomic 函数,这篇文章接着探讨ARM架构和总线协议如何来支持的。对于某款ARM处理器和总线CCI,CCN和CMN产品的具体实现,属于实现层面的微架构,一般需要NDA,这里不予讨论。
顺便提一下,在ARMv8 架构下对应的是LDXR (load exclusive register 和STXR (store exclusiveregister)及其变种指令,另外,在ARMv8.1架构中引入atomic instruction, 例如LDADD (Atomic add),CAS(Compare and Swap)等。
Exclusive monitor
首先,作为一个爱问为什么的工程师,一定会想到LDXR/ STXR和一般的LDR/STR有什么区别。这个区别就在于LDXR除了向memory发起load请求外,还会记录该memory所在地址的状态(一般ARM处理器在同一个cache line大小,也就是64 byte的地址范围内共用一个状态),那就是Open和Exclusive。
我们可以认为一个叫做exclusive monitor的模块来记录。根据CPU访问内存地址的属性(在页表里面定义),这个组件可能在处理器 L1 memory system, 处理器cluster level, 或者总线,DDR controller上。
下面是Arm ARM架构 [1] 文档定义的状态转换图
实例说明:
1)CPU1发起了一个LDXR的读操作,记录当前的状态为Exclusive
2)CPU2发起了一个LDXR的读操作,当前的状态为Exclusive,保持不变
3)CPU2发起了一个STXR的写操作,状态从Exclusive变成Open,同时数据回写到DDR
4)CPU1发起了一个STXR的写操作,因为当前的exclusive monitor状态为Open,写失败(假如程序这时用STR操作来写,写会成功,但是这个不是原子操作函数的本意,属于编程错误)
假如有多个CPU,同时对一个处于Exclusive的memory region来进行写,CPU有内部逻辑来保证串行化。
Monitor的状态除了STXR会清掉,从Exclusive变成Open之外,还有其他因素也可以导致monitor的状态被清掉,所以软件在实现spinlock