Linux内核:自旋锁SMP:为​​什么在spin_lock_irq SMP版本中有一个preempt_disable()?

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); } 

我认为没有执行path可以抢占本地IRQ禁用后的当前path。

由于所有常见的硬中断禁止,不应该发生softirq,也没有打勾时间表轮。 我认为目前的道路是安全的。 那么为什么有一个preempt_disable()?

谢谢。

Solutions Collecting From Web of "Linux内核:自旋锁SMP:为​​什么在spin_lock_irq SMP版本中有一个preempt_disable()?"

据我所知,在2002年12月4日,Dave Miller将相当多的锁定原语(包括spin_lock_irq preempt_disable()添加到preempt_disable()调用中,并在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 ... 

我撇清了Sharp提到的补丁 ,发现禁用irq可以隐式禁用抢占,但风险很大。

但是,请记住,依靠被禁用的是一个冒险的业务。 任何将抢占计数减少到0的spin_unlock()都可以触发重新计划。 即使是一个简单的printk()也可能触发这样的重新安排。 所以只有当你知道这样的事情不可能发生在你的代码路径中时,才依靠隐式抢占 – 禁用。 最好的策略是依靠隐式抢占 – 仅在短时间内禁用,只要您保留在自己的代码中。