14.9.6 软中断处理线程(ksoftirqd)
在前面曾经介绍过,对于软中断,内核会选择在几个特殊时刻进行处理。而在中断处理程序返回时处理软中断是最常见的。软中断被触发的频率有时可能会很高(例如,进行大流量的网络通信期间)。而且更糟糕的是软中断处理程序在执行时还可重新触发自己使其再次执行(也就是在软中断处理程序中调用raise_softirq或raise_softirq_irqoff函数使当前软中断再次挂起)。如果软中断本身出现的频率很高,再加上软中断可能会将自己重新置为可执行状态。这样就会导致用户空间的进程无法获取足够的处理器时间,因而处于饥饿状态。造成这种饥饿状态是由于Linux内核会立即对重新触发的软中断进行处理。然而,单纯的对重新触发的软中断采取不立即处理的策略也会让人发疯的。这样一来,虽然用户空间的程序可以获得足够的处理器时间。但对硬件的响应就会出现问题。如果这时系统很忙(运行的用户空间程序太多),就会出现系统迟迟不响应硬件的现象,很可能还会造成死机。现在将这两种最初的解决方案归纳如下。
立即处理重新触发的软中断。可能会造成用户空间应用程序无法获得足够的处理器时间。
不立即处理重新触发的软中断。也就是说当中断处理程序返回时值处理所有挂起的软中断,由这些软中断触发的其他软中断暂时不会处理,直到下次中断处理程序返回或其他适当的时机才会处理这些软中断。这种解决方案也有问题,如果系统处于空闲状态,无疑立即处理被重新触发的软中断是一个好主意,可在这种情况下仍然将处理延后就有点不合适。这样会造成大量的处理器时间浪费。使用这种解决方案可能会造成Linux系统对硬件的响应不及时。
这两种方法相当于"鱼"和"熊掌"。看似不可兼得。当然聪明的Linux内核开发者还是想出来一种折中的方案,从而使我们同时可以尝到"鱼"和"熊掌"的美味。这就是本节要讨论的ksofti