• 【转】中断处理函数中不用disable_irq而用disable_irq_nosync原因


    原文网址:http://blog.csdn.net/skyflying2012/article/details/8265869

    今天在写触摸屏驱动时在中断处理函数中使用disable_irq关中断发现在进入中断处理后内核就挂掉了,于是研究了一下才发现disable_irq关闭中断并等待中断处理完后返回, 而disable_irq_nosync立即返回. 在中断处理程序中应该使用disable_irq_nosync来关闭中断
     
    先看一下disable_irq_nosync,内核代码中是这样解释的:

    /**
     *    disable_irq_nosync - disable an irq without waiting
     *    @irq: Interrupt to disable
     *
     *    Disable the selected interrupt line. Disablesand Enables are
     *    nested.
     *    Unlike disable_irq(),this function doesnot 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);
    }

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


    /**
     * 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.
     */
    void disable_irq(unsignedint 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函数中.


    /**
     * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
     * @irq: interrupt number to wait for
     *
     * 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.
     */
    void synchronize_irq(unsignedint irq)
    {
     struct irq_desc *desc= irq_to_desc(irq);
     unsigned int status;
     if (!desc)
      return;
     do {
      unsigned long flags;
      /*
       * Wait until we're out of the critical section. This might
       * give the wrong answer due to the lack of memory barriers.
       */
      while (desc->status& IRQ_INPROGRESS)
       cpu_relax();
      /* Ok, that indicated we're done: double-check carefully. */
      spin_lock_irqsave(&desc->lock, flags);
      status = desc->status;
      spin_unlock_irqrestore(&desc->lock, flags);
      /* Oops, that failed? */
     } while (status & IRQ_INPROGRESS);
     /*
      * We made sure that no hardirq handler is running. Now verify
      * that no threaded handlers are active.
      */
     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独占而发生系统崩溃.
  • 相关阅读:
    C#模拟键盘登录网站
    利用c#开发一个telnet unix服务器或者防火墙的小工具(转)
    Fckeditor XML Request error:internal server error (500) 一例
    CSS格式模板
    TFS 2008: Message that "solution not currently configured for integrated source control in Visual Studio"
    学习笔记Javascript事件Event、IE浏览器下的拖拽效果
    学习笔记验证控件
    学习笔记Socket编程、任务栏图标和MD5散列算法
    学习笔记Web服务、Remoting、WCF (上) Web服务
    学习笔记Web服务、Remoting、WCF (下) Remoting and WCF
  • 原文地址:https://www.cnblogs.com/wi100sh/p/4875093.html
Copyright © 2020-2023  润新知