1.在中断调用disable_irq();会导致cpu stuck,这个其实就是中断的禁忌,不能被调度或者挂起,而disable_irq()不符合这个条件,
所以要慎用,最好不要用,除非你能保证它不被挂起,不过这是不可能的。
2.在中断可以调用disable_irq_nosync()这个函数不会pend;
实现现象,多核cpu, cpu2被lock,watchdog被触发重启。
[ 545.709737] INFO: rcu_preempt detected stalls on CPUs/tasks: { 2} (detected by 3, t=2102 jiffies, g=1653, c=1652, q=144)
[ 545.719578] Task dump for CPU 2:
[ 545.722787] ksoftirqd/2 R running 0 19 2 0x00000002
[ 545.729152] [<c020f8b0>] (__schedule) from [<c024af4c>] (smpboot_thread_fn+0x25c/0x274)
[ 545.737124] [<c024af4c>] (smpboot_thread_fn) from [<c0245270>] (kthread+0xd8/0xec)
[ 545.744673] [<c0245270>] (kthread) from [<c0208d20>] (ret_from_fork+0x14/0x34)
[ 553.625490] Watchdog bark! Now = 553.625475
[ 553.628645] Causing a watchdog bite!
[ 553.632027] Configuring Watchdog Timer
函数功能介绍:
/**
* disable_irq_nosync - disable an irq without waiting
* @irq: Interrupt to disable
*
* Disable the selected interrupt line. Disables and Enables are
* nested.
* Unlike disable_irq(), this function does not ensure existing
* instances of the IRQ handler have completed before returning.
*
* This function may be called from IRQ context.
*/
这个不会等handler完成就返回,所以不会deadlock
void disable_irq_nosync(unsigned int irq)
{
__disable_irq_nosync(irq);
}
/**
* disable_irq - disable an irq and wait for completion
* @irq: Interrupt to disable
*
* Disable the selected interrupt line. Enables and Disables are
* nested.
* This function waits for any pending IRQ handlers for this interrupt
* to complete before returning. If you use this function while
* holding a resource the IRQ handler may need you will deadlock.
*
* This function may be called - with care - from IRQ context.
*/
这个会等handler完成返回,如果在中断中使用,那么就会必然会deadlock
void disable_irq(unsigned int irq)
{
if (!__disable_irq_nosync(irq))
synchronize_irq(irq);
}