Linux内核:Spinlock SMP:为​​什么spin_lock_irq SMP版本中有preempt_disable()?

时间:2012-11-07 05:21:37

标签: linux kernel spinlock smp

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都被禁用,所以不应该出现softirq,也没有勾选计划轮。我认为目前的道路是安全的。那么为什么会有preempt_disable()?

谢谢。

2 个答案:

答案 0 :(得分:7)

据我所知,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 ...

答案 1 :(得分:3)

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

  

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