您的位置:首页 > 运维架构 > Linux

Linux中断处理流程

2013-08-02 10:16 218 查看
以下的语句都是摘自网络上的资料,自己再综合总结一下。
Linux的中断处理遵循了“重要的事情,马上做。不重要的事情,推后做”。
 
MIPS平台下的do_IRQ处理函数。
1:  void __irq_entry do_IRQ(unsigned int irq)


2:  {


3:      irq_enter();


4:      __DO_IRQ_SMTC_HOOK(irq);


5:      generic_handle_irq(irq);


6:      irq_exit();


7:  }


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

MIPS平台下的generic_handle_irq经过层层调用,会调用对应模块通过request_irq函数注册的中断处理函数。

      一般情况下,中断处理函数是在关中断的情况下运行的,为了提高效率,尽量减少关中断的时间,于是有了soft_irq机制,把一部分不需要在关中断情况下执行的代码放在中断外面执行。具体就是调用raise_softirq去设置一个软中断,由open_softirq来注册对应的软中断处理程序,用来处理一些不太紧急的中断处理程序。

在软中断机制中,为每个CPU维护了一个若干位的掩码集,每位掩码代码一个中断号,每位中断号于raise_softirq绑定的中断号相对应。

中断有其对应的优先级,每个CPU处理属于自己的中断。在软中断处理函数中开中断进行处理。

实际上,软中断很少直接使用,由tasklet机制来调用软中断。实际中,在进入中断处理程序后,在完成关中断的部分,调用tasklet_schedule/tasklet_hi_schedule标记一个tasklet,中断处理程序结束。后面的工作由HI_SOFTIRQ/TASKLET_SOFTIRQ对应的软中断处理程序去处理被标记的tasklet。

softirq<---->每个CPU,每个CPU处理自己的softirq(可重入函数,可能在多个CPU上同时运行),常用于时钟中断处理过程和网络收发处理过程。

tasklet是在多个CPU间被串行化执行,处理函数不必考虑可重入的问题。

CPU中断处理完成后,需要恢复之前保存在栈上的寄存器信息,恢复中断之前的运行状态。

softirqtaskletworkqueue
轮询所有中断(限制软中断为32个)无差别队列机制,有中断时才执行

效率比softirq高,支持SMP,无数量限制
一组内核线程,作为中断守护线程来使用
尽量不用推荐使用要用到线程才能用到的某些机制时,推荐使用。
softirq ―> tasklet ―>workqueue

轮训处理所有软中断

可能存在的两方面的问题:

连续的低优先的中断可能持续占有CPU,而高优先的某些进程则无法获得CPU。

中断处理的整个阶段,不能调用可能导致睡眠的函数(信号量,分配内存,阻塞式IO申请等等)

 

对与第一个问题:

新版的Linux内核增加的ksoftirqd的内核线程。如果持续处理的softirq超过了一定数量,则结束中断处理程序,然后唤醒ksoftirq来继续处理。

linux内核提供了工作队列机制来解决上述问题,workqueue。定义一个workqueue结构(包含了处理函数),在中断处理的过程中,调用schedule_work函数,work便加入到workqueue中,等待处理。工作队列有自己的处理线程,这些work被推迟到这些线程中处理,处理过程只可能发生在这些工作线程中,因此,加入到工作队列中的处理函数可以睡眠。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: