Linux内核为将中断服务分为两部分提供了方便,并设立了相应的机制。在以前的内核中,这个机制就叫bottom half(简称bh),但在2.4版中有了新的发展和推广,叫做软中断(softirq)机制。
1.Bh机制
以前内核中的Bh机制设置了一个函数指针数组bh_base[],它把所有的后半部分都组织起来,其大小为32,数组中的每一项就是一个后半部分,即一个bh 函数。同时,又设置了两个32位无符号整数bh_active和bh_mask,每个无符号整数中的一位对应着bh_base[]中的一个元素,如图3.9所示:
图3.9 bh机制示意图
在2.4以前的内核中,每次执行完do_IRQ()中的中断服务例程以后,以及每次系统调用结束之前,就在一个叫do_bottom_half()的函数中执行相应的bh函数。
在do_bottom_half()中对bh函数的执行是在关中断的情况下进行的,也就是说对bh的执行进行了严格的“串行化”,这种方式简化了bh的设计,这是因为,对单CPU来说,bh
函数的执行可以不嵌套;而对于多CPU来说,在同一时间内最多只允许一个CPU执行bh函数。
这种简化了的设计在一定程度上保证了从单CPU到多CPU SMP结构的平稳过渡,但随着时间的推移,就会发现这样的处理对于SMP的性能有不利的影响。因为,当系统中有很多个bh函数需要执行时,bh函数的“串行化”却只能使一个CPU执行一个bh函数,其它CPU即使空闲,也不能执行其它的bh函数。由此可以看出,bh函数的串行化是针对所有CPU的,根本发挥不出多CPU的优势。
那么,在新内核的设计中,是改进bh机制还是抛弃bh机制,建立一种新的机制?2.4选择了一种折中的办法,继续保留bh机制,另外增加一种或几种机制,并把它们纳入一个统一的框架中,这就是2.4内核中的软中断(softirq)机制。
2.软中断机制
软中断机制也是推迟内核函数的执行,然而,与bh函数严格地串行执行相比,软中断却在任何时候都不需要串行化。同一个软中断的两个实例完全有可能在两个CPU上同时运行。当然,在这种情况下,软中断必须是可重入的。软中断给网络部分带来的好处尤为突出,因为2.4内核中用两个软中断代替原来的一个NET_BH函数,这就使得在多处理机系统上软中断的执行更为高效。
3.Tasklet机制
另一个类似于bh的机制叫做tasklet。Tasklet建立在软中断之上,但与软中断的区别是,同一个tasklet只能运行在一个CPU上,而不同的tasklet可以同时运行在不同的CPU上。在这种情况下,tasklet就不需要是可重入的,因此,编写tasklet比编写一个软中断要容易。
Bh机制在2.4中依然存在,但不是作为一个单独的机制存在,而是建立在tasklet之上。因此,在2.4版中,设备驱动程序的开发者必须更新他们原来的驱动程序,用tasklet代替bh。