内核的竞态控制
何谓竞态?用一句话描述就是:并行执行的多个程序,同时访问共享资源,或执行同一段代码,若这些行为是有害的则称此为竞态
1.解决机制
- 现代soc大多是对称多处理器机制(SMP),每个核可以有自己的中断,自己的进程(宏观和微观都是并行)。如下
可以认为,SMP是竞态最复杂的情况了,单核竞态的复杂度真包含于SMP。由于驱动程序需要保证稳定性与普适性,所以最好一律按照SMP的情况来进行竞态控制 - 解决竞态的途径,即:某个程序在访问共享资源时,禁止其他程序访问;执行同一段代码时,禁止其他程序也来执行。
- 根本途径其实是使用ARM指令集中各种“屏障指令”,详细的指令就不展开了。这些指令是Linux中各种竞态控制手段的根本实现方式
2.辅助措施——中断屏蔽
中断屏蔽操作只能屏蔽本 CPU 内的中断,因此并不能解决 SMP多核引发的多个中断之间的竞态。故中断屏蔽一般和自旋锁、互斥锁配合使用
local_irq_disable() /* 屏蔽中断 */
. . .
/* 临界区*/
. . .
local_irq_enable() /* 开中断*/
/*下面是更推荐的方式*/
local_irq_save(flags)/*暂停中断*/
. . .
/* 临界区*/
. . .
local_irq_restore(flags)/*恢复中断*/
- 长时间屏蔽中断是很危险的,有可能造成数据丢失乃至系统崩溃等后果。这就要求在屏蔽了中断之后,当前的内核执行路径应当尽快地执行完临界区的代码
3.原子操作
原子操作是一种简单的解决竞态的机制,保证了整数操作和位操作不被打断
- 设置整形变量的值
void atomic_set(atomic_t *v, int i);