内核杂谈——qspinlock的流程理解

在高版本内核中,arm64的spinlock加入了MCS锁的实现机制,改为qspinlock

独占

原先的实现方式是arch_spin_lock,使用ldaxr和stxr指令实现锁变量的修改。这两个指令暗含独占监视器的功能。

啰嗦一下独占操作的理解:

ldxr和stxr是成对出现的。L = local;G = global

对于一个内存地址,没被任何cpu访问的话是开放的,任何cpu都可以去占有这段地址,只要cpu执行ldxr就会标记此内存已被占有(L)。

假设有一块内存,两个cpu都ldxr,各自标记独占。当一个cpu执行stxr修改了独占的内存,操作完后该内存会重新回归开放状态(G),这里的开放所有cpu都看得到。

当另一个cpu想去执行stxr,发现曾经的独占已经不是独占(L)了,则无法修改,必须重新回归ldxr操作重新标记独占(L)。

简而言之,当你追求的小姑娘有太多的追求者,你想让小姑娘靠近你,你有可能需要重新耍花招。因为小姑娘会随时离你而去。

qspinlock加锁流程

这里以代码里的注释图来做解释,不涉及具体的代码阅读。(tail,pending,locked)代表一个锁,这个不清楚的话下面的内容建议不要看。

存在一个拿锁对象

若无cpu持有锁,A直接获取锁,将locked置位。这是非竞争态

存在两个拿锁对象

如果该锁已被A持有。B也来获取锁,进入路线1,设置pending。然后进入路线2不断等待A释放锁,如果读到locked位为0,代表锁可以持有,进入路线3,清除自己设置的pending,然后获取锁,将locked置位。

存在三个拿锁对象

如果A持有锁,B也在等待,此时来了C也要获取锁,这时会将C加入MCS锁队列,设置tail值来记录C。然后进入路线2不断等待锁被释放,如果读到locked位和pending位为0,代表A和B都已经用完了锁,锁可以持有,进入路线3,获取锁,将lock置位,清除tail位。此时队列中只有C,是一个非竞争队列。

存在四个拿锁对象

如果A持有锁,B也在等待,C也要获取锁在MCS等待队列中,D也要来获取锁,更新tail值,这时的tail代表D,然后会将D放到C的后面,形成一个竞争队列。当C拿到锁后会通知D准备拿锁,等到C释放锁后拿锁,在此之前在路线2等待锁被释放。当锁空闲进入线路3获取锁将locked置位。

qspinlock中的MCS锁队列

入队

qnode是per cpu变量,qnode[0]的作用是count计数,最终会和当前的cpu一起设置到tail位中。MCS锁队列中可能存放的是同一个cpu上的不同场景的持锁请求

MCS锁队列中也可能存放的是不同cpu持锁请求

当然也可能是混合的,这里不列举。

tail位代表最新加入的节点,在更新tail位的时候会先获取旧值,以便找到队尾,然后将新节点加入队列

获取锁(出队)

第一个加入队列的等待者等待pending和locked位清0,而后面加入队列的等待者等待的是本地变量locked置1(注意前者是qspinlock 的locked,后者是mcs_spinlock的locked)。

如果队列里不止一个等待者,第一个等待者拿到锁以后会设置下一个等待者的本地locked位,这样下一个等待者转而去等待locked位清0然后获取锁

拿到锁以后count会减一,这样就代表销毁了这个节点。这里有个疑问

release:
	/*
	 * release the node
	 */
	__this_cpu_dec(qnodes[0].mcs.count);

这里count减一后,再来一个同一个cpu上的等待者,count加一,是不是和现有的最后一个等待者冲突了?

qspinlock竞争

qspinlock加入了MCS锁队列整合了MCS的优点,减少了全局竞争。我们可以看出竞争只发生在pending和lock位的读取,读取这两个位只发生在两个竞争者之间。如果有三个竞争者,最后来的竞争者等待的是本地qnode里的locked位,并不存在全局竞争。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值