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()?
谢谢。
答案 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()也可能会触发这种情况 重新安排。因此,只有你依赖隐式抢占 - 禁用 知道在你的代码路径中不会发生这种事情。该 最好的策略是依赖隐式抢占 - 仅禁用 只有在您自己的代码中保留的时间很短。