【问题标题】:spin_lock on non-preemtive linux kernels非抢占式 Linux 内核上的自旋锁
【发布时间】:2011-03-23 07:12:47
【问题描述】:

我读到,在具有 1 个 CPU 和非抢占式 linux 内核 (2.6.x) 的系统上,spin_lock 调用等同于空调用,因此以这种方式实现。

我不明白:它不应该等同于在互斥体上休眠吗?例如,即使在非抢占式内核上,中断处理程序仍可能会被执行,或者我可能会调用一个使原始线程进入睡眠状态的函数。因此,如果将空的 spin_lock 调用作为互斥锁实现,那么它不是“安全的”。

有什么我不明白的吗?

【问题讨论】:

    标签: locking linux-kernel mutex spinlock


    【解决方案1】:

    如果您要在非抢占式内核上使用spin_lock() 来屏蔽数据免受中断处理程序的影响,您会死锁(在单处理器机器上)。

    如果中断处理程序在其他内核代码持有锁时运行,它将永远旋转,因为常规内核代码无法恢复并释放锁。

    只有当锁持有者可以一直运行到完成时,才能使用自旋锁。

    中断处理程序可能需要锁定的解决方案是使用spin_lock_irqsave(),它在自旋锁被持有时禁用中断。使用 1 个 cpu,没有中断处理程序可以运行,因此不会出现死锁。在 smp 上,一个中断处理程序可能会开始在另一个 cpu 上旋转,但是由于持有锁的 cpu 不能被中断,所以锁最终会被释放。

    【讨论】:

      【解决方案2】:

      回答你问题的两个部分:

      即使在非抢占式内核上,中断处理程序仍可能被执行,例如 ...

      spin_lock() 不应该防止中断处理程序 - 只有用户上下文内核代码。 spin_lock_irqsave() 是中断禁用版本,这不是非抢占式单处理器上的空操作。

      ...或者我可能会调用一个使原始线程进入睡眠状态的函数。

      持有自旋锁时不允许休眠。这是“原子时调度”错误。如果您想睡觉,则必须改用互斥锁(同样 - 这些不是非抢占式单处理器上的空操作)。

      【讨论】:

        【解决方案3】:

        引自 «Linux Device Drivers»,作者 Jonathan Corbet、Alessandro Rubini 和 Greg Kroah-Hartman:

        如果一个非抢占式单处理器系统曾经在一个 锁,它会永远旋转;没有其他线程能够做到 获取 CPU 以释放锁(因为它无法让步)。 因此,单处理器系统上的自旋锁操作无需 启用抢占被优化为什么都不做,除了 改变 IRQ 屏蔽状态的那些(在 Linux 中,这将是 spin_lock_irqsave())。因为抢占,即使你从来没有 期望您的代码在 SMP 系统上运行,您仍然需要实现 适当的锁定。

        如果您对在中断上下文(硬件或软件)中运行的代码可以采用的自旋锁感兴趣,则必须使用禁用中断的spin_lock_* 形式。不这样做会在您进入临界区时在中断到达时立即使系统死锁。

        【讨论】:

        • 实际上,抢占式单处理器系统的情况是一样的,因为 spin_lock 调用禁用了抢占。
        • -1 用于复制/粘贴而不注明出处。引用时,请写清楚,至少提供原作者姓名! books.google.ch/…
        【解决方案4】:

        根据定义,如果您使用的是非抢占式内核,您将不会被抢占。如果您自己进行多任务处理,那不是内核的问题;那是你的问题。中断处理程序可能仍会执行,但不会导致上下文切换。

        【讨论】:

        • 另外,这是否意味着我不能在我的自旋锁关键部分进行可能阻塞的调用? (比如 kmalloc 或 printk?)
        • 自旋锁不应被 IRQ 使用,除非自旋锁的所有其他用户在获取锁之前禁用 IRQ(请参阅 Erics 回答)。如果允许,您描述的情况将导致死锁(处理器在 IRQ 处理程序中旋转,但如果处理器不运行另一段代码,则永远无法释放锁)。
        • @happy_emi 要回答您的其他问题,在持有自旋锁时,您不应进行可能阻塞、休眠或重新安排的调用,因为这也可能导致死锁。
        猜你喜欢
        • 1970-01-01
        • 2018-09-16
        • 1970-01-01
        • 1970-01-01
        • 2011-07-10
        • 2015-03-05
        • 2014-01-13
        • 2017-03-05
        • 2014-08-25
        相关资源
        最近更新 更多