【问题标题】:Linux Kernel: Spinlock SMP: Why there is a preempt_disable() in spin_lock_irq SMP version?Linux 内核:Spinlock SMP:为​​什么 spin_lock_irq SMP 版本中有 preempt_disable()?
【发布时间】:2012-10-27 03:27:32
【问题描述】:

Linux内核原代码为:

static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)
{
    local_irq_disable();
    preempt_disable();
    spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
    LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
}

我认为在本地 IRQ 被禁用后,没有执行路径可以抢占当前路径。

因为所有常见的硬 IRQ 都被禁用,所以应该不会发生软中断,也不会出现启动调度轮的滴答声。我认为目前的道路是安全的。那么为什么会有preempt_disable()呢?

【问题讨论】:

  • @cnicutar.你确定吗?我不这么认为。每个 CPU 内核都使用 schedule() 来选择要运行的作业。在具有多核的 SMP 系统中,每个核都有一个专用的执行路径,就像 UP 系统一样。在这种情况下,本地 IRQ 被禁用,因此该内核上的调度轮被阻塞。可能抢占发生在另一个 CPU 上,但这不会影响这个 CPU 上的执行路径,我认为它们是专用于执行级别的。

标签: c linux kernel spinlock smp


【解决方案1】:

我浏览了Sharp提到的patch,发现禁用irq可以隐式禁用抢占但是有风险。

但是,请记住,依赖 irq 被禁用是有风险的 商业。任何将抢占计数减少到 0 的 spin_unlock() 可以触发重新安排。即使是一个简单的 printk() 也可能触发这样的 重新安排。因此,仅当您使用隐式抢占禁用时 知道这种事情不会发生在您的代码路径中。这 最好的策略是仅依赖于隐式抢占禁用 时间很短,只要你留在自己的代码中。

【讨论】:

    【解决方案2】:

    据我所知,preempt_disable() 调用已添加到相当多的锁定原语中,包括 spin_lock_irq,由 Dave Miller 于 2002 年 12 月 4 日在 2.5.51 中发布。提交消息没有帮助;它只是说“[SPINLOCK]:修复非 SMP nopping spin/rwlock 宏。”

    我相信Proper Locking Under a Preemptible Kernel 文档很好地解释了这一点。标题为“使用中断禁用防止抢占”的最后一节开始,

    It is possible to prevent a preemption event using local_irq_disable and
    local_irq_save.  Note, when doing so, you must be very careful ...
    

    【讨论】:

    • ,您的评论很有帮助。非常感谢。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多