`
java-mans
  • 浏览: 11423482 次
文章分类
社区版块
存档分类
最新评论

再思linux内核在中断路径内不能睡眠/调度的原因(2010)

 
阅读更多

Linux内核中断路径中不能睡眠,为什么?

这里就行了很深入的讨论,值得一看:http://bbs2.chinaunix.net/viewthread.php?tid=1618430

但是,他们的讨论最后没有得出一个明确的结论。其中,cskyrain在8楼 的思考触及到了一个要点,但是没有深入展开:

7楼:

8楼:

总体上,大家得到的初步结论是:内核在中断路径内不能睡眠,不是技术上做不到,而是没有理由这么做,或者说在中断路径上睡眠不合理。一方面,外部事件导致当前进程时间片被剥夺,不合理;一方面,中断服务程序应该尽快处理完中断,保证IO吞吐率。

-------------------------------分割线----------------------------

通过阅读ULK中文版第三版164页的内容,让我对这个问题有了一个较为清晰的认识:

内核在编译的时候设置了THREAD_SIZE的值为8K的话, 那么每个进程的内核栈的大小就为8K, 此时如果发生中断时, 那么进程的寄存器等值就会保存到它的8K的内核栈中. 但是如果设置了THREAD_SIZE的大小为4K的话, 内核就会使用3种类型的内核栈, 异常栈, 硬件中断请求栈以及软中断请求栈( When using 4K stacks, interrupts get their own stack instead of using the currently active kernel stack.)

* 异常栈:每个进程一个。

* 硬中断请求栈:每个CPU一个,每个占用一个单独的页框。do_IRQ()函数内部通过调用execute_on_irq_stack负责切换到该栈中来。

* 软中断请求栈:每个CPU一个,每个占用一个单独的页框。

关于切换到中断栈的方法,请看下面的代码:

最后,思考一下标题中的问题:linux内核在中断路径内不能睡眠/调度的原因

Linux是以进程为调度单位的,调度器只看到进程内核栈,而看不到中断栈。在独立中断栈的模式下,如果linux内核在中断路径内发生了调度(从技术上讲,睡眠和调度是一个意思),那么linux将无法找到“回家的路”,未执行完的中断处理代码将再也无法获得执行机会。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics