Linux 中断上下文(二)

Linux中断上下部机制

1 linux系统中对中断的处理上下部的之分

中断处理程序处于中断上下文,而中断上下文是不参与调度的,这样中断上下文不能出现可能休眠的操作,因为中断上下文一旦休眠就会交出cpu,而中断上下文不参与调度,也就是交出cpu时不会保存上下文,这样一旦交出cpu就永远不会回来了。这也就决定了在中断中不能和用户空间进行数据交互,因为这种交互可能会引起休眠。
还有一点,为了尽量提高系统的响应速度,中断程序运行的时间应该尽可能短。比如说中断来临后系统在处理中断服务程序,此时有一个事件发生,如果这个事件的优先级没有此时的中断优先级高,这个事件就会等待中断处理完成,而中断处理的时间越长,该事件等待的时间就越长,因为中断是不能被调度的,这样就会导致事件的响应速度很差,也就是响应性能不好。
除以以上的考虑,中断处理程序分解为两个半部:顶半部(Top Half)和底半部(Bottom Half)。

顶半部用于完成尽量少的比较急的功能,他往往知识简单的读取寄存器中的中断状态,并在清除中断标志后就进行“登记中断”的工作。“登记中断”意味着将底半部处理程序挂到该设备的底半部执行队列中去。这样,顶半部执行的速度就会很快,从而可以服务更多的中断请求。
现在,中断处理工作的重心就落在底半部的头上,需用它来完成中断事件的绝大多数任务。底半部几乎做了中断处理程序所有的事情,而且可以被新的中断打断,这也是底半部和顶半部的最大的不同,因为顶半部往往被设计成不可中断。底半部相对按理说并不是非常紧急的,而且相对比较耗时的,不在硬件中断服务程序中执行。

2 Linux 底半部机制

Linux实现底半部的机制主要有tasklet、workqueue、softirq和线程化irq。
必须立即进行的紧急处理的极少数任务应该放在中断的上半部中,此时是屏蔽了与自己同类型的中断的,任务量少,可以迅速的完成紧急任务。

需要较少时间的中等数量的急迫任务放在tasklet的下半部,tasklet的下半部工作在中断上下文,不会被调度,但是其不会屏蔽任何中断(包括与自己上半部同类型的中断),所以并不影响其他上半部对紧急任务的处理,同时自己不会被调度也能保证自己的急迫任务被迅速完成。

需要较多时间且不急迫的大量任务放在workqueue的下半部,workqueue的下半部工作在进程上下文,参与调度。其调度优先级比较高,操作系统会尽量先完成其任务,但是当其任务时间太长,操作系统也会调度去执行其他的用户进程,从而保证其他用户进程不至于死掉

总结:可能引起休眠的任务放在workqueue的下半部,因为其他的都工作在中断上下文,是不能被休眠的;在需要获得大量内存时、需要获取信号量时、阻塞操作时放在workqueue的下半部,因为获取大量内存时、获取信号量与阻塞操作时都可能会引起休眠。

猜你喜欢

转载自blog.csdn.net/u013836909/article/details/107235289