只是好奇为什么spin_lock_irqsave
在禁用本地中断后需要禁用抢占。
static inline unsigned long __raw_spin_lock_irqsave(raw_spinlock_t *lock)
{
unsigned long flags;
local_irq_save(flags);
preempt_disable(); ===> can preemption happen with interrupt disabled?
spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
...
}
只有启用中断才能进行抢占,因此在禁用中断后不必担心抢占。
答案 0 :(得分:0)
因为存在一些导致抢占的函数,除非显式禁用了抢占,而无论中断状态如何。假设是如果不允许抢占,它将被明确禁用,并且该功能也不会抢占。使用中断来禁止抢占会违反该假设。
一个这样的函数是cond_resched(),它在core.c(https://elixir.bootlin.com/linux/v5.9-rc5/source/kernel/sched/core.c#L6116)中调用_cond_resched()
它检查是否启用了抢占并调用调度程序。在内核中的许多地方都可以调用此函数,并且有可能意外触发其中之一,从而破坏了自旋锁保护的关键部分。
此外,禁用中断自旋锁意味着可以从中断处理程序访问关键部分。如果您不小心使用cond_resched()触发了抢占,一旦您的进程得到调度,将重新启用后向中断。如果发生试图获取锁的中断,则将导致死锁。