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

Zhi*_*ang 9 linux kernel smp spinlock

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);
}
Run Code Online (Sandbox Code Playgroud)

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

因为所有常见的硬IRQ都被禁用,所以不应该出现softirq,也没有勾选计划轮.我认为目前的道路是安全的.那么为什么会有preempt_disable()?

谢谢.

Jam*_*arp 8

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

我相信在一个可抢占的内核文档正确锁定很好地解释了这一点.最后一节标题为"预防使用中断禁用的预防"开始,

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 ...
Run Code Online (Sandbox Code Playgroud)


kik*_*_yu 5

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

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