使用spin_lock和spin_lock_irqsave,死锁?

时间:2012-10-07 05:40:11

标签: c linux locking kernel deadlock

我正在阅读一些代码,我在函数foo中看到了:

// x is a global variable shared by all functions
spin_lock(&x);
if(some condition)
    function();
spin_unlock(&x);

in function();

// do stuff
spin_lock_irqsave(&x, vals);
....

如果“某些情况”属实,会不会出现死锁?这似乎太明显了,所以我想也许我错过了什么?

由于

编辑:代码不是linux的一部分,它只是我在网上发现的一些随机代码

3 个答案:

答案 0 :(得分:1)

此代码将死锁(假设没有递归锁定,这是一些Linux内核代码)。通常,当您希望保护代码不被中断抢占时,使用irq版本的spin_lock。

vals的原因是保存当前的中断状态并在调用irqrestore时恢复它。这是为了避免在抓取多个自旋锁或处于禁用中断的块中时过早地中断。

答案 1 :(得分:1)

旋转锁是not recursive,可能永远不会,因为它们是高性能锁。

因此,如果条件为真,则发布的代码将会死锁。

答案 2 :(得分:0)

这取决于spin_lock()spin_lock_irqsave()的实施方式。

例如,它们可能确定锁是否已被同一CPU锁定并且如果是,则递增计数器;然后(当锁定被释放时)递减计数器并且只有在计数器变为零时才释放锁定。这样,同一个CPU可以多次获取锁,并且不会导致死锁。

spin_lock_irqsave()也可以是仅禁用IRQ的东西,它实际上并不获取锁定(例如,假设/期望spin_lock()事先被调用的东西)。在这种情况下,锁&x可能只是一个方便的位置来存储/跟踪IRQ被禁用的事实(并且可能spin_unlock()检查一些标志并在它们被禁用时再次启用IRQ)。

但是,我无法想到spin_lock_irqsave()需要第二个参数(vals)的原因。

另一种可能性是这些功能的名称具有误导性,与它们实际上完全没有任何关系。例如; spin_lock()功能可能会订购比萨饼,而spin_lock_irqsave()功能可能会显示足球比赛结果。

基本上,除了名称之外,没有关于这些功能的信息,因此无法确定它们的作用(或者是否存在死锁)。