linux disable_irq() and disable_irq_nosync()

 


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] [] (__schedule) from [] (smpboot_thread_fn+0x25c/0x274)
[  545.737124] [] (smpboot_thread_fn) from [] (kthread+0xd8/0xec)
[  545.744673] [] (kthread) from [] (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);
}

 

你可能感兴趣的:(内核及驱动相关)