【问题标题】:Using spin_lock and spin_lock_irqsave, deadlock?使用 spin_lock 和 spin_lock_irqsave,死锁?
【发布时间】:2012-10-07 05:40:11
【问题描述】:

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

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

在函数()中;

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

如果“某些条件”为真,会不会出现死锁?这似乎太明显了,所以我想也许我错过了什么?

谢谢

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

【问题讨论】:

  • 是什么代码,才能避免?

标签: c linux locking kernel deadlock


【解决方案1】:

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

vals的原因是为了保存当前的中断状态,在调用irqrestore的时候恢复。这是为了避免在获取多个自旋锁或处于中断被禁用的块中时过早打开中断。

【讨论】:

    【解决方案2】:

    自旋锁是not recursive,可能永远不会是,因为它们旨在成为高性能锁。

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

    【讨论】:

      【解决方案3】:

      这取决于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() 函数可能会显示足球结果。

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

      【讨论】:

      • 不错的答案,除了 spin_lockspin_lock_irqsavedocumented Linux kernel functions。无需猜测他们在做什么。
      • 问题明确指出:“代码不是linux的一部分,只是我在网上找到的一些随机代码”。我认为Linux 标签是错误的。
      • ...然后标签是linuxkernel。我将其解释为“这不在 Linux 内核中,它是在线的随机内核代码。”
      猜你喜欢
      • 1970-01-01
      • 2015-10-26
      • 2021-05-06
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 2018-09-11
      • 2021-01-03
      • 1970-01-01
      相关资源
      最近更新 更多