您的位置:首页 > 其它

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

2013-11-22 15:37 387 查看
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独占而发生系统崩溃.

阅读(325) | 评论(0) | 转发(0) |

0
上一篇:使用DDD+GDB开发ARM Linux程序

下一篇:linux驱动,中断中关闭中断

相关热门文章

中断处理程序中的关中断函数di...

中断处理函数中不用disable_ir...

中断处理程序中的关中断函数di...

承接自动化测试培训、外包、实...

Solaris PowerTOP 1.0 发布

For STKMonitor

busybox的httpd使用CGI脚本(Bu...

项目小体会

修改默认端口为222,centos自...

用PHP做一个ftp登录页面...

Toad for Oracle工具,为什么在...

本地win7安装vmw9系统winserv...

powermt config是所什么用的...

给主人留下些什么吧!~~

评论热议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: