我是靠谱客的博主 悲凉大炮,最近开发中收集的这篇文章主要介绍在中断上下文使用disable_irq()的…,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

跟着<linux设备驱动开发详解>编写键盘驱动,驱动老是崩溃,整了我一天的时间,后来发现是disable_irq()的问题,貌似是个bug或者LDDR3有错。

disable_irq关闭中断并等待中断处理完后返回, 而disable_irq_nosync立即返回. 那么在中断处理程序中应该使用哪一个函数来关闭中断呢?
在<linux设备驱动开发详解>中的按键驱动中, 使用disable_irq来关闭中断, 但是我在测试时进入中断后系统会死在中断处理程序, 而改为disable_irq_nosync则能正常退出中断处理程序.下面从内核代码来找一下原因:
先看一下disable_irq_nosync,内核代码中是这样解释的:

/**
 *    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.
 */
void disable_irq_nosync(unsigned int irq)
{
    struct irq_desc *desc = irq_to_desc(irq);
    unsigned long flags;

    if (!desc)
        return;

    chip_bus_lock(irq, desc);
    spin_lock_irqsave(&desc->lock, flags);
    __disable_irq(desc, irq, false);
    spin_unlock_irqrestore(&desc->lock, flags);
    chip_bus_sync_unlock(irq, desc);
}


关闭中断后程序返回, 如果在中断处理程序中, 那么会继续将中断处理程序执行完.


void disable_irq(unsigned int irq)
{
        struct irq_desc *desc = irq_desc + irq;
        if (irq >= NR_IRQS)
                return;
        disable_irq_nosync(irq);
        if (desc->action)
                synchronize_irq(irq);
}


关闭中断并等待中断处理完后返回.从代码中可以看到, disable_irq先是调用了disable_irq_nosync, 然后检测desc->action是否为1. 在中断处理程序中, action是置1的, 所以进入synchronize_irq函数中.


void synchronize_irq(unsigned int irq)
{
 struct irq_desc *desc = irq_to_desc(irq);
 unsigned int status;
 if (!desc)
  return;
 do {
  unsigned long flags;
  

  while (desc->status & IRQ_INPROGRESS)
   cpu_relax();
  
  spin_lock_irqsave(&desc->lock, flags);
  status = desc->status;
  spin_unlock_irqrestore(&desc->lock, flags);
  
 } while (status & IRQ_INPROGRESS);
 

 wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active));
}


注释中说明该函数是在等待中断处理程序的结束, 这也是disable_irq与disable_irq_nosync不同的主要所在. 但是在中断处理函数中调用会发生什么情况呢? 进入中断处理函数前IRQ_INPROGRESS会被__setup_irq设置, 所以程序会一直陷在while循环中, 而此时内核以经被独占, 这就导致系统死掉.
 
总结:
由于在disable_irq中会调用synchronize_irq函数等待中断返回, 所以在中断处理程序中不能使用disable_irq, 否则会导致cpu被synchronize_irq独占而发生系统崩溃.

最后

以上就是悲凉大炮为你收集整理的在中断上下文使用disable_irq()的…的全部内容,希望文章能够帮你解决在中断上下文使用disable_irq()的…所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部