2010年7月20日19:18:30 关于中断处理程序中的关中断函数disable_irq和disable_irq_nosync
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);
}


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

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

/**
 * 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(unsigned int 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独占而发生系统崩溃.

关于中断处理程序中的关中断函数disable_irq和disable_irq_nosync相关推荐

  1. Linux中断不能进行任务调度,关中断是否禁止任务调度?关中断能作为互斥吗?...

    今天再看<嵌入式软件系统教程>((美)西蒙 著,陈向群 等译)  ,里面讲到关中断会关了任务调度,作者没说原因,我也不知道为什么,所以查了查网络. ==================== ...

  2. linux中断处理程序架构,Linux外部中断架构初始化流程-----Tiny6410

    arch/arm/plat-s3c64xx/irq-eint.c文件实现了S3C64XX系列的外部中断初始化,这是一个内核模块,入口点是s3c64xx_init_irq_eint,声明如下: arch ...

  3. linux进程被中断打断,linux – 当中断处理程序被另一个中断中断时,中断上下文如何“恢复”?...

    我读了一些相关的帖子: You cannot sleep in an interrupt handler because interrupts do not have a backing proces ...

  4. 优化缩短关中断的时间

    文章目录 1 优化缩短关中断的时间 1.1 提取耗时操作 1.2 划分为多次开关中断 1 优化缩短关中断的时间 无论是开关全局中断还是关指定中断,都会对中断的响应时间造成影响.关中断的时间越长,中断被 ...

  5. 使用关中断解决资源冲突问题

    文章目录 1 使用关中断解决资源冲突问题 1 使用关中断解决资源冲突问题 解决方法如下: 注意事项: 适用于嵌套中断间共享资源: 在开启了中断嵌套后,可能发生嵌套中断访问同一共享资源.此时,也可以使用 ...

  6. 中断处理程序与中断服务例程

    版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 1 什么是中断 2中断处理程序 3中断服务例程 4request_irq函数分析 1. 什么是中断 简单来说中断就是硬件设备与处 ...

  7. 操作系统——中断处理程序及设备驱动程序

    中断处理程序及设备驱动程序 中断是指CPU在执行一个程序时,对系统中发生的某个事件做出的一个反应,它在操作系统中有着重要的有着重要的地位,时多道程序得以实现的基础. 引入缓冲区的原因: 外部中断:简称 ...

  8. linux 中断服务程序,request_irq() linux注册中断服务

    在 2.4 内核和 2.6内核中都使用 request_irq() 函数来注册中断服务函数.在 2.4 内核中,需要包含的头文件是 #include ,2.6 内核中需要包含的头文件则是 #inclu ...

  9. arm汇编 调用linux中断,GNU ARM汇编(四)中断汇编之非嵌套中断处理

    原标题:GNU ARM汇编(四)中断汇编之非嵌套中断处理 在写这篇blog之前,不得不感慨一句:纸上得来终觉浅,绝知此事要躬行.作为EE出身的,虽然好久好久没用汇编写 的中断了,但自我感觉对中断的理解 ...

最新文章

  1. 淘宝面试:说一下 ThreadLocal 的原理?网友:现在面试不看源码不行啊~
  2. 疫情撬动游戏产业“底层认知”,正向价值愈发突显
  3. 坑 之 tensorflow使用sess.run处理图片时越来越慢,占用内存越来越大的问题
  4. 两部手机怎样才能把数据都传过来_我把魅族换成荣耀,30G的数据文件该如何一键转移?...
  5. cp命令的编写——浅谈系统调用
  6. php文件锁解锁是删除对应的文件_软件 | 文件解锁强制删除工具 Wise Force Deleter v1.49...
  7. wordpress多站点主站调用分站最新文章_企业网站SEO最新的7个优化步骤!
  8. spock测试_将Spock 1.3测试迁移到Spock 2.0
  9. nessuss中文使用手册
  10. JdbcTemplate操作
  11. Hive 分区表操作 创建、删除
  12. 第3课 攀天梯(ladder)--记忆化搜索(python3实现)
  13. 如何利用计算机实现非线性转换,基于cass数控绕线机非线性算法的设计与实现-计算机应用技术专业论文.docx...
  14. [javax.validation]验证
  15. java适配器模式 场景_详解Java适配器模式
  16. ROST SEAT使用方法
  17. R语言常用数据文件的导入
  18. x7 z8750 linux,x7-z8750 vs m3-7y30
  19. 知网论文[全PDF下载],从此告别CAJ阅读器
  20. 文本特征提取:词袋模型/词集模型,TF-IDF

热门文章

  1. android 环形时间显示_Android圆形进度条颜色的设置
  2. React Native debug debugger
  3. Codeforces1063D Candies for Children 【分类讨论】【暴力】
  4. Logistic Regression逻辑回归
  5. jyphon 环境变量配置
  6. 卸载Macports,安装HomeBrew
  7. CentOS开启FTP及配置用户
  8. 使用泛型查询数据小例
  9. 福州华威集团旗下华威客运票务网页界面设计
  10. 最简android之wifi调试