(八)下半部和推后执行的工作
整个中断处理流程被分为两个部分,第一个部分是中断处理程序(上半部),第二个部分叫做下半部。
下半部
下半部的任务就是执行与中断处理密切相关但中断处理程序本身不执行的工作。在理想情况下,最好是中断处理程序将所有工作都交给下半部分执行,因为我们希望在中断处理程序中完成的工作越少越好,能够尽快地返回。
什么任务应该在哪个部分中完成————如何做决定完全取决于驱动程序开发者自己的判断。可借鉴的点:
如果一个任务对时间非常敏感,将其放在中断处理程序中执行;
如果一个任务和硬件相关,将其放在中断处理程序中执行;
如果一个任务要保证不被其他中断打断,将其放在中断处理程序中执行;
其他所有任务,考虑放置在下半部执行。
上半部分简单快速,执行的时候禁止一些或者全部中断。下半部分稍后执行,而且执行期间可以响应所有的中断。这种设计可使系统处于中断屏蔽状态的时间尽可能的短,以此来提高系统的响应能力。
当前有三种机制可以用来实现将工作推后执行:软中断、tasklet和工作队列。
软中断
软中断使用得比较少,而tasklet是下半部更常用的一种形式。但是tasklet是通过软中断实现的。
软中断是在编译期间静态分配的,注册的软中断数目的最大值没法动态改变。
一个软中断不会抢占另外一个软中断。实际上,唯一可以抢占软中断的是中断处理程序。不过,其他的软中断可以在其他处理器上同时执行。
tasklet
tasklet是通过软中断实现的,所以它们本身也是软中断。
通常应该使用tasklet作为下半部机制
工作队列
工作队列可以把工作推后,交由一个内核线程去执行——这个下半部分总是会在进程上下文中执行。最重要的是工作队列允许重新调度甚至是睡眠。
如果推后执行的任务需要睡眠,那么就选择工作队列。如果推后执行的任务不需要睡眠,那么就选择软中断或tasklet。
在下半部之间加锁
在使用下半部机制时,即使是在一个单处理器的系统上,避免共享数据被同时访问也是至关重要的。