Chinaunix首页 | 论坛 | 博客
  • 博客访问: 23704
  • 博文数量: 14
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-19 06:31
文章分类
文章存档

2013年(14)

我的朋友

分类: LINUX

2013-06-05 22:57:48

disable_irq关闭中断并等待中断处理完后返回, 而disable_irq_nosync立即返回. 那么在中断处理程序中应该使用哪一个函数来关闭中断呢? 在中的按键驱动中, 使用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独占而发生系统崩溃.
阅读(941) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~