这段代码仍然处于 lock1 的临界区,如果此时硬件中断也需要申请 lock1 锁会导致死锁,这是因为 spin_unlock_irq 在解锁时一定会将本地 CPU 的中断打开,从而导致硬件中断可以重新强制抢占 CPU,所以最好的方式就是 lock2 在锁之前保存当前的中断状态,在解锁时恢复当前的中断状态,这也就是 spin_lock_irqsave
LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } 可以看出来他们两者只有一个差别:是否调用local_irq_disable()函数, 即是否禁止本地中断。在任何情况下使用spin_lock_irq都是安全的。因为它既禁止本地中断,又禁止内核抢占。spin_lock比spin_lock_irq速度快,但是它并不是任何情况下都是安...
spin_unlock(&lock); 他能正常工作吗?答案是有可能。在某些情况下,这段代码可以正常工作,但如果发生如下调用关系: // in normal run level extern spinlock_t lock; spin_lock(&lock); // run... -->>// interrupted by IRQ ... // in IRQ spin_lock(&lock); // run... spin_unlock(&lock);...
spin_lock/spin_lock_irqsave 保护的临界区内禁止调用可能使CPU睡眠/发生调度的函数(包括但不限于ioremap/mutex/semaphore等),否则可能出现死锁引起CPU挂死等问题。 CPU挂死问题在编码压力测试下出现,经过排查和复测已明确是上述原因导致;上周前端反馈出现VB申请不到打印后,CPU立即挂死,原因也是ISP驱动内部也出现上述...
spin_trylock_irq()与spin_trylock()两个函数都是非阻塞式的自旋锁获取操作,不成功即返回,都不会引起调用者睡眠。 主要区别在于对中断的处理上。spin_trylock()不改变当前中断状态,而spin_trylock_irq()则会在操作前临时禁用中断,操作后恢复中断状态,确保了操作的原子性。
在Linux内核中何时使用spin_lock,何时使用spin_lock_irqsave很容易混淆。首先看一下代码是如何实现的。 spin_lock的调用关系 spin_lock | + ---> raw_spin_lock [cpp] view plaincopy static inline void __raw_spin_lock(raw_spinlock_t *lock) { ...
对于spin lock,其保护的资源可能来自多个CPU CORE上的进程上下文和中断上下文的中的访问,其中,进程上下文包括:用户进程通过系统调用访问,内核线程直接访问,来自workqueue中work function的访问(本质上也是内核线程)。中断上下文包括:HW interrupt context(中断handler)、软中断上下文(soft irq,当然由于各种原因,该softirq被推...
在SMP机器上,我们必须使用spin_lock_irqsave而不是来自中断上下文的spin_lock_irq。 为什么我们要保存标志(包含IF)? 是否有另一个中断例程可以中断我们? 请您参考如下方法: 我是内核的新手,但是从我从罗伯特·洛夫(Robert Love)的书“Linux Kernel Development”(Linux内核开发)中了解到的情况来看,如果在代码开始锁...
在Linux内核中何时使用spin_lock,何时使用spin_lock_irqsave很容易混淆。首先看一下代码是如何实现的。 spin_lock的调用关系 spin_lock | + ---> raw_spin_lock [cpp] view plaincopy static inline void __raw_spin_lock(raw_spinlock_t *lock) { ...
spin_lock_irqsave():此函数保存中断的当前状态,并禁止本地中断,然后再去获取指定的锁 spin_unlock_irqrestore():对指定的锁解锁,然后让中断恢复到加锁前的状态 所以即使中断最初是禁止的,代码也不会错误地激活它们,相反,会继续让它们禁止 flags变量看起来像是由数值传递的,这是因为这些锁函数有些部分是通过宏的...