免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4496 | 回复: 4
打印 上一主题 下一主题

[中断] 再问中断处理程序为什么不能睡眠? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-10-31 15:09 |只看该作者 |倒序浏览
本帖最后由 frank529 于 2012-11-01 09:26 编辑

这个问题有很多人问,但感觉一直没有一个合理的解释。参见帖子《关于LINUX在中断(硬软)中不能睡眠的真正原因》:
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=2115820

先来看这个问题的起源(ULK中文第三版147页):
允许内核控制路径嵌套执行必须付出代价,那就是中断处理程序必须永不阻塞,换句话说,中断处理程序运行期间不能发生进程切换。事实上,嵌套的内核控制路径恢复执行时需要的所有数据都存放在内核态堆栈中,这个栈毫无疑义的属于当前进程。

英文版:
The price to pay for allowing nested kernel control paths is that an interrupt handler must never block, that is, no process switch can take place until an interrupt handler is running. In fact, all the data needed to resume a nested kernel control path is stored in the Kernel Mode stack, which is tightly bound to the current process.

根据这段描述,我们可以得到以下几点信息:
1、中断是可以嵌套的,即文中所说的“内核控制路径嵌套”,意思就是一个中断服务程序可以被高优先级的中断打断。
2、中断处理程序不能阻塞的原因是由于中断嵌套。
3、中断上下文是保存在当前进程的内核栈中。

参考帖子《关于LINUX在中断(硬软)中不能睡眠的真正原因》的回复,大家认为中断服务程序不能嵌套的原因大致有以下几点:
1、中断上下文不像进程上下文,没法保存,也就是中断服务程序睡眠了就再也切不回来了
2、中断是一种紧急事务,必须立即处理,比如时钟中断,一睡眠的话系统时间都乱了

我认为以上观点都没道理,理由如下:
1、参考ULK给出的信息2,中断不能睡眠是由于中断可以嵌套,以上理由跟中断嵌套没有关系
2、参考ULK给出的信息3,中断上下文是保存着当前进程的内核栈中,而且每个进程都有各自的内核栈,互不影响。既然保存了上下文,中断服务程序切走了当然还能切回来,而且切到其他进程也不影响其他进程响应新的中断。
3、第二个理由只是说明紧急中断不应该睡眠,而不是中断不能睡眠的理由。我在中断服务程序里先把紧急的事干了,后面的事不紧急了,凭啥不让我睡眠?就算切换到其他进程,它还是能再次响应中断。

因此,我觉得问题应该这么问:为什么中断嵌套的代价是中断服务程序不能阻塞?

希望高手能给个一针见血的回答。

论坛徽章:
0
2 [报告]
发表于 2012-10-31 16:24 |只看该作者
本帖最后由 frank529 于 2012-10-31 16:28 编辑

补充:
ULK中文第三版147页后面又写道:
“Page Fault(缺页)”异常发生在内核态...当处理这样一个异常时,内核可以挂起当前进程,并用另一个进程代替它,直到请求的页可以使用为止。只要被挂起的进程又获得处理器,处理缺页异常的内核控制路径就恢复执行。

与异常形成对照的是,尽管处理中断的内核控制路径代表当前进程运行,但由于I/O设备产生的中断并不引用当前进程专有的数据结构。事实上,当一个给定的中断发生时,要预测哪个进程将会运行是不可能的。

这里说明了:
缺页异常处理程序是可以挂起的,缺页异常也是中断。所以前面说的“中断服务程序不能阻塞”里的“中断”指的是其他I/O设备产生的中断,是相对于异常而言的。

后面那段红色的字似乎想要解释原因,但说得不清不楚,还是不明白。

论坛徽章:
0
3 [报告]
发表于 2012-10-31 17:08 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
4 [报告]
发表于 2012-10-31 21:53 |只看该作者
两个不太靠谱、互补的理由:
    - 中断处理程序有负担,要求速入速出;
    - 扰乱了调度体系。线程化中断可以解决这个问题,但基于上一条理由,仍不推荐睡眠。

论坛徽章:
0
5 [报告]
发表于 2012-11-01 09:12 |只看该作者
本帖最后由 frank529 于 2012-11-01 10:31 编辑
tempname2 发表于 2012-10-31 21:53
两个不太靠谱、互补的理由:
    - 中断处理程序有负担,要求速入速出;
    - 扰乱了调度体系。线程化 ...


中断处理程序有什么负担?就是中断上下文吧,无法就是消耗一点内核栈空间而已,所以我觉得第一条理由不成立。如果中断可以睡眠,那就没必要分成上下半了,都在中断服务程序处理就行了,紧急先处理了,然后有条件的睡眠,条件满足了再切回来执行非紧急的部分。

你第二条说的很有道理,当前中断可能跟当前进程没有任何关系,在中断处理程序里睡眠了,就阻塞了当前进程,影响了当前进程的调度。


所谓“中断不能睡眠”应该这么描述:由于中断服务程序使用了当前进程的内核栈,而硬件IO中断可能在任何时间发生,这个中断可能与当前进程没有任何关系,如果在中断服务程序中睡眠,会导致当前进程毫无理由的被阻塞,扰乱了进程的调度。


ULK说的中断服务程序不能阻塞实在是太笼统了。系统调用也是中断,缺页异常也是中断,这些中断服务程序都是可以睡眠的,因为它们的发生是与当前进程密切相关的,而硬件IO的中断不一定与当前进程有关,所以不能因为硬件IO的中断服务程序而无故阻塞当前进程。


至于Linux为了简化设计而人为的禁止中断服务程序睡眠那又是另外一回事了,这里不作讨论。




您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP