只是好奇为什么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_);
...
}抢占应该只有在中断启用的情况下才能实现,因此在禁用中断后不需要担心抢占。
发布于 2020-09-17 21:50:47
因为存在导致抢占的功能,除非明确地禁用抢占,而不管中断的状态。假设如果不允许抢占,那么它将被显式禁用,并且该功能不会被抢占。相反,使用中断来禁用抢占违反了这一假设。
一个这样的函数是cond_resched(),它调用core.c (https://elixir.bootlin.com/linux/v5.9-rc5/source/kernel/sched/core.c#L6116)中的_cond_resched()
它检查是否启用了抢占,并调用调度程序。这个函数是从内核中的许多地方调用的,可能会意外触发其中的一个,从而破坏受自旋锁保护的临界区。
此外,中断禁用自旋锁意味着您的临界区可以从中断处理程序访问。如果您意外地使用cond_resched()触发了抢占,那么一旦您的进程被调度回来,就会重新启用中断。如果发生尝试获取锁的中断,则会出现死锁。
https://stackoverflow.com/questions/27210315
复制相似问题