critical section Linux内核同步 - spin_lock(11)

电脑杂谈  发布时间:2018-02-14 08:19:43  来源:网络整理

static inline void arch_spin_lock(arch_spinlock_t *lock)

{

unsigned long tmp;

__asm__ __volatile__(

"1: ldrex %0, [%1]\n"

" teq %0, #0\n"

WFE("ne")

" strexeq %0, %2, [%1]\n"

" teqeq %0, #0\n"

" bne 1b"

: "=&r" (tmp)

: "r" (&lock->lock), "r" (1)

: "cc");

smp_mb();

}

这段内嵌汇编首先检查lock->lock,如果等于0,就表明现在是unlock状态,就把lock->lock置位1,表示lock状态。这段汇编里边,关键的三个指令是:ldrex, strexeq, WFE, 前两个指令实现独占访问储存器,保证"读取-修改-写入”在芯片级是原子的,而WFE是wait for event, 和WFI类似,只是他可以被SEV指令唤醒,在spin_unlock()的时候,会发出SEV。

具体可以参见蜗蜗的文章:

了解SMP 平台下的spin_lock之后,还是那两个问题,进程上下文重入和中断上下文重入。第一个问题已经澄清,那第二个问题呢?重现之前的情景:进程A陷入内核,获取spin_lock,正在执行临界区代码,被本地IRQ打断,且ISR中要获取同一个spin_lock, 在SMP下,ISR就要调用WFE进入low-power-mode,这样持有锁的内核路径也得不到运行,所以无法释放锁资源,ISR也就只能一直WFE,本地CPU就这样挂掉了。当然,当IRQ在其他CPU上的时候,这种情况是不会发生的,另一个CPU为WFE直到本地CPU释放锁资源。

所以,这样又回到之前的解决办法,如果ISR有可能重入临界区,那么就应该使用 spin_lock_irq() 而非 spin_lock()。如果不这样使用,在UP下,临界数据将错乱,而在SMP下,CPU将死锁。


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-77053-11.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...