免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 31220 | 回复: 24

中断处理程序为什么不能阻塞休眠???以前真没认真思考过! [复制链接]

论坛徽章:
0
发表于 2009-11-24 20:36 |显示全部楼层
一直认为中断处理函数不能休眠的是天经地义的,可从没认真思考过问什么不能休眠,阻塞。最近看了一下ulk中对这个的解释,感觉还是有点不太明白,
“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.”
上面把中断处理程序不能休眠归结为中断处理程序可以嵌套,而恢复嵌套的中断处理程序的相关数据放在内核态堆栈中,这个栈和当前进程相关联,这里有一点不明白,既然有栈存储数据,而且进程切换出去后,这个栈也不会被销毁,等进程在切回来时,不同样可以是嵌套的中断处理程序返回吗?(这里先不考了中断处理时间的太长,影响对中断处理的服务问题,只说明中断是否可休眠)。同时我google一下,看到有人对中断不能休眠的以一种解释:

中断处理程序用到的所有数据有保存在当前进程的内核堆栈中(一般情况下),如果此时发生了
进程切换,中断处理程序将被阻塞, 当在一次发生进程切换时,不一定马上就换回来。比如当
发生一个键盘中断时,键盘处理程序正在进行,此时又恰好发生了进程抢占,切换到了另一个进程
中,假如那个进程不会引起内核的稳定,那么中断处理程序将一直阻塞,内禾根本就没法响应那个中断,
直到在一次发生进程切换。假设最后又切换回执行中断处理程序的那个进程中时,如果它的内核堆栈
受到了无意的破坏怎么办呢?那中断处理程序可能无法在继续运行下去了,此次中断服务失败。而且
现在的处理程序都允许中断嵌套,一个中断被阻塞,其它的都将被阻塞。所以面对错综复杂的内核逻辑,
最好的办法就是在中断处理程序中禁止发生进程切换,这样既提高了中断处理程序的响应速度,也增加了
内核的稳定性与安全性。


我感觉他的理由有两个:一个事效率,可能影响处理速度,另一就是:如果它的内核堆栈
受到了无意的破坏怎么办?
对于第一种理由先不讨论,
可第二种,理由我感觉很牵强,如果栈那么容易破坏,哪我也可以说描述进程的数据结构什么的也可能被破坏,哪岂不是进程调度都是不安全的了,
这样按他的说法,就只有第一个效率的原因了。

回到ulk的解释,不知道是不是我理解的有问题,The price to pay for allowing nested kernel control paths is that an interrupt handler must never block
感觉他把中端不能休眠的原因都归结为可支持中断处理程序的嵌套上了。那是不是可以这样理解,如果不支持中断嵌套,中断处理程序就可以休眠了,呵呵呵,貌似这样也不对吧,
问题:中断处理程序不能休眠的原因究竟是什么呢?

论坛徽章:
0
发表于 2009-11-24 21:37 |显示全部楼层

暂时的理解是:
只有在一定条件下,中断才会产生,中断一但休眠,则产生中断的条件可能会丧失,那样中断处理程序执行还有什么意义?
具体不懂,请大虾指点

论坛徽章:
0
发表于 2009-11-25 08:23 |显示全部楼层
记得这个问题去年内核版激烈讨论过,很精彩,去翻翻贴子吧

论坛徽章:
0
发表于 2009-11-25 09:51 |显示全部楼层
原帖由 cskyrain 于 2009-11-24 20:36 发表
一直认为中断处理函数不能休眠的是天经地义的,可从没认真思考过问什么不能休眠,阻塞。最近看了一下ulk中对这个的解释,感觉还是有点不太明白,
“The price to pay for allowing nested kernel control path ...


我的理解是中断的发生是不和任何进程关联的,如果它被block,那么它的上下文肯定要被保存下来以恢复执行,但是怎么恢复它执行呢?
只能是把中断产生那个时刻正在运行的进程的状态设置为block之类的,等重新调度。
这对进程显然是不合理的:我运行得好好的,你中断优先级高,那我可以让你运行,你完了如果不发生调度,那么还是我运行。但是凭什么你中断被block就要把我block?

与之相对,系统调用可以被block,因为它关联到具体的一个进程。是进程本身的请求得不到满足,那么应该被block。

所以,中断的上下文实际上是独立的上下文,与进程上下文无关,不参与调度。系统调用仍然是进程的上下文。

论坛徽章:
0
发表于 2009-11-25 09:57 |显示全部楼层

回复 #4 huangwei0413 的帖子

“我的理解是中断的发生是不和任何进程关联的”
早些的内核中断的确是和进程相关关联的。

”系统调用可以被block,因为它关联到具体的一个进程。是进程本身的请求得不到满足,那么应该被block。“
这个有道理!我一直也认为系统调用不是原子的,但是可重入。

论坛徽章:
0
发表于 2009-11-25 10:38 |显示全部楼层

回复 #4 huangwei0413 的帖子

完全的晕了,如果说系统调用不是原子的,也就是说系统调用可以block,该系统调用代表的进程可以被切换出去,
问题来了,系统调用实际上是通过int80软中断实现的,中断是不能block的啊,这样不是矛盾了吗?

论坛徽章:
0
发表于 2009-11-25 11:52 |显示全部楼层

回复 #6 cskyrain 的帖子

中断不能block,应该特指异步中断吧。
看了LZ这两天的帖子,我觉得还是类似4楼的说法比较靠谱:异步中断是独立的上下文,与当前进程无关,所以不能因为中断上下文的block而将无辜的进程给block了。可能就是基于这一初衷吧~ 那些已经将中断处理程序线程化了的实时linux应该是允许中断block的。
而同步的中断(比如系统调用、缺页异常)是代表当前进程的,本来就是可以block的。

论坛徽章:
0
发表于 2009-11-25 12:14 |显示全部楼层

回复 #7 kouu 的帖子

呵呵,又翻了翻书,思考了一下,由于时间问题,没心情再从头读ulk,只是跳着查了一下,难免会漏下很多东西,不过还是说说我的理解:
这里中断只代表异步中断,异常代表同步中断,这样系统调用是异常处理,不是中断处理。
这里异常处理是可以休眠block的,因为异常处理所需的数据是存储在异常栈中,而每个进程都有一个异常栈,所以异常处理和进程是相关联的,这样异常处理可以block,被调度出去。
而对于中断,分为两种情况,一种是中断使用单独的中断栈而不使用进程的内核栈的情况,这样,由于所有中断共享一个中断栈,这个中断栈不和特定进程关联,所以,这种中断时不能block的,block后他是不能再被调度。
第二种情况是,中断不使用单独的中断栈,而是使用当前进程的内核栈,这种情况我认为是和异常处理时一样的,这种中断时可以block的,之所以不准许中断block不是技术上切换不回来,而是逻辑上为了提高处理的效率强制其不能block。

以上是我现阶段的理解,感觉,前俩个的解释应该没什么问题,但最后对不是用中断栈的中断的解释可能有错误的认识,不知kouu对这种解释有何看法?

论坛徽章:
0
发表于 2009-11-25 13:22 |显示全部楼层

回复 #8 cskyrain 的帖子

嗯,我的想法也差不多。
不过,中断是可以嵌套的,如果block了,不光是阻塞了当前进程、还阻塞了被嵌套的那些中断处理过程;
而异常是不会嵌套的,否则就是double fault了,这应该属于内核BUG

论坛徽章:
0
发表于 2009-11-25 13:30 |显示全部楼层
一个异步中断特殊,就是时钟中断。
这个可以休眠。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP