为解决一次中断需要做大量工作的问题,Linux将对中断的处理划分为两个部分:上半部是实际响应中断的程序,也就是传统意义上的中断服务程序,只能完成紧急和必要的功能。
下半部则是完成其他延缓的任务,下半部处理期间所有中断是开着的。
一、下半部的实现机制
1、BH机制,定义了一个函数指针,共32个,这些函数指针存放在数组中;所一内核定义了一组枚举变量,每种中断对应一个函数。其缺点就是个数限制,而且不能两个机制同时运行。
2、任务队列,将任务队列取代BH机制,每个队列包含一个有延缓执行的函数组成的链表。内核使用struct tq_struct描述延缓执行的任务,使用时驱动都可以使用DECLARE_TASK_QUEUE宏定义自己的任务队列,然后定义一个struct tq_struct变量,并将其注册到自己定义的队列上,之后可以通过手工调用run_task_queue()函数执行队列中的所有任务。
3、软中断,沿用BH机制,定义了一个32的软件数组(由struct softirq_action描述),每个被注册的软中断都占据该数组中的一项,他们可以在所有CPU上同时执行,即使是相同类型的软中断。
一个软中断只能被中断服务程序抢占,而不会去抢占其他软中断。中断服务程序再返回前会触发其软中断以使其稍后执行,然后内核在执行完该中断服务程序后,就会马上调用do_softirq()函数,执行软中断完成剩余任务。
4、tasklet(本身就是软中断)
是利用软中断实现的一种下半部机制。与软中断相比,两个不同类型的tasklet可以在不同CPU上同时执行,但相同类型的不能同时执行。也就是说同一个tasklet只会在一个CPU上运行。
5、工作队列
与软中断和tasklet不同的是,工作队列吧延缓的工作交由一个内核线程去执行,一次通过工作队列执行的代码是运行在进程上下文的,允许重新调度和睡眠。
二、下半部机制的选择
1、BH机制和任务队列在2.6内核已不使用;
2、软中断和tasklet运行于中断上下文,工作队列靠内核线程实现,运行于进程上下文。因此如果需要将任务推迟到进程上下文完成,工作队列是必然的选择,否则另外两个合适,因为工作队列会带来上下文切换的消耗。
3、相对于软中断来说,tasklet对锁的要求低的多。如果要使用下半部的模块代码本身对于保护考虑的不好,选择tasklet;
4、易用性考虑,首先是工作队列,其次tasklet,最后是软中断;
5、需要一个调度的实体来执行需要推后完成的工作,即有休眠的需要,则必须使用工作队列,否则最好用tasklet,如果必须专注性能的提高,那就考虑软中断吧。
下半部则是完成其他延缓的任务,下半部处理期间所有中断是开着的。
一、下半部的实现机制
1、BH机制,定义了一个函数指针,共32个,这些函数指针存放在数组中;所一内核定义了一组枚举变量,每种中断对应一个函数。其缺点就是个数限制,而且不能两个机制同时运行。
2、任务队列,将任务队列取代BH机制,每个队列包含一个有延缓执行的函数组成的链表。内核使用struct tq_struct描述延缓执行的任务,使用时驱动都可以使用DECLARE_TASK_QUEUE宏定义自己的任务队列,然后定义一个struct tq_struct变量,并将其注册到自己定义的队列上,之后可以通过手工调用run_task_queue()函数执行队列中的所有任务。
3、软中断,沿用BH机制,定义了一个32的软件数组(由struct softirq_action描述),每个被注册的软中断都占据该数组中的一项,他们可以在所有CPU上同时执行,即使是相同类型的软中断。
一个软中断只能被中断服务程序抢占,而不会去抢占其他软中断。中断服务程序再返回前会触发其软中断以使其稍后执行,然后内核在执行完该中断服务程序后,就会马上调用do_softirq()函数,执行软中断完成剩余任务。
4、tasklet(本身就是软中断)
是利用软中断实现的一种下半部机制。与软中断相比,两个不同类型的tasklet可以在不同CPU上同时执行,但相同类型的不能同时执行。也就是说同一个tasklet只会在一个CPU上运行。
5、工作队列
与软中断和tasklet不同的是,工作队列吧延缓的工作交由一个内核线程去执行,一次通过工作队列执行的代码是运行在进程上下文的,允许重新调度和睡眠。
二、下半部机制的选择
1、BH机制和任务队列在2.6内核已不使用;
2、软中断和tasklet运行于中断上下文,工作队列靠内核线程实现,运行于进程上下文。因此如果需要将任务推迟到进程上下文完成,工作队列是必然的选择,否则另外两个合适,因为工作队列会带来上下文切换的消耗。
3、相对于软中断来说,tasklet对锁的要求低的多。如果要使用下半部的模块代码本身对于保护考虑的不好,选择tasklet;
4、易用性考虑,首先是工作队列,其次tasklet,最后是软中断;
5、需要一个调度的实体来执行需要推后完成的工作,即有休眠的需要,则必须使用工作队列,否则最好用tasklet,如果必须专注性能的提高,那就考虑软中断吧。