免费注册 查看新帖 |

Chinaunix

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

关于LINUX在中断(硬软)中不能睡眠的真正原因 [复制链接]

论坛徽章:
0
1 [报告]
发表于 2007-06-27 10:09 |显示全部楼层
呵呵,我最喜欢这种讨论了。先来献丑了,说说我的看法。
先把中断处理流程给出来

  1. 1.进入中断处理程序--->2.保存关键上下文---->3.开中断(sti指令)--->4.进入中断处理程序的handler--->5.关中断(cli指令)---->6.写EOI寄存器(表示中断处理完成)---->7.开中断。
复制代码

硬中断:
对应于上图的1、2、3步骤,在这几个步骤中,所有中断是被屏蔽的,如果在这个时候睡眠了,操作系统不会收到任何中断(包括时钟中断),系统就基本处于瘫痪状态(例如调度器依赖的时钟节拍没有等等……)

软中断:
对应上图的4(当然,准确的说应该是4步骤的后面一点,先把话说保险点,免得思一克又开始较真 )。这个时候不能睡眠的关键是因为上下文。
大家知道操作系统以进程调度为单位,进程的运行在进程的上下文中,以进程描述符作为管理的数据结构。进程可以睡眠的原因是操作系统可以切换不同进程的上下文,进行调度操作,这些操作都以进程描述符为支持。
中断运行在中断上下文,没有一个所谓的中断描述符来描述它,它不是操作系统调度的单位。一旦在中断上下文中睡眠,首先无法切换上下文(因为没有中断描述符,当前上下文的状态得不到保存),其次,没有人来唤醒它,因为它不是操作系统的调度单位。
此外,中断的发生是非常非常频繁的,在一个中断睡眠期间,其它中断发生并睡眠了,那很容易就造成中断栈溢出导致系统崩溃。

如果上述条件满足了(也就是有中断描述符,并成为调度器的调度单位,栈也不溢出了,理论上是可以做到中断睡眠的),中断是可以睡眠的,但会引起很多问题.例如,你在时钟中断中睡眠了,那操作系统的时钟就乱了,调度器也了失去依据;例如,你在一个IPI(处理器间中断)中,其它CPU都在死循环等你答复,你确睡眠了,那其它处理器也不工作了;例如,你在一个DMA中断中睡眠了,上面的进程还在同步的等待I/O的完成,性能就大大降低了……还可以举出很多例子。所以,中断是一种紧急事务,需要操作系统立即处理,不是不能做到睡眠,是它没有理由睡眠。

好了,罗嗦了一大堆,大家见仁见智,不要骂人就好。

评分

参与人数 1可用积分 +15 收起 理由
albcamus + 15 精品文章

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2007-06-27 10:31 |显示全部楼层
原帖由 思一克 于 2007-6-27 10:21 发表于 6楼  
那么LINUX有在中断中睡眠的地方吗

据我所知没有。但有没有人在他自己写的驱动程序的中断处理handler中睡眠就不知道了

论坛徽章:
0
3 [报告]
发表于 2007-06-28 10:37 |显示全部楼层
原帖由 xiaozhaoz 于 2007-6-27 22:00 发表于 19楼  


里面很多说法不是很同意, 个人认为中断处理handler不能sleep原因应该不是上面那些.

我们都是从理论讲下面这些问题, 因为linux在很多地方做了保护, 所以直接sleep或者schedule()会导致内核异常.

首先分 ...

>>这其实和"中断没有自己的上下文"无关. CPU没有关中断, 中断有自己的上下文, 中断的上下文就是抢占的任务A的上下文.

“中断没有自己的上下文”,呵呵,我没有说这句话哈。lz很多立论在这句话上,估计是看贴的时候看错了。

>>假设中断sleep了, 在调度的时候, 内核将中断的CS:eip和SS:esp保存在被抢占任务A的thread_info中, 当任务A被重新唤醒的时候, 任务A从中断的CS:eip开始执行, 这也能正常执行下去, 中断执行完后, 从ret_from_intr中返回. 可以恢复任务A的抢占前的场景.

这里在中断sleep了,由谁来唤醒呢?关键还是没有一个中断描述符来作为内核调度的单位。
前面也说到了,这是个设计问题,不是能不能实现的问题。
如果说把中断的handler作为一组内核线程,当然是可以让中断睡眠的。但我始终任为中断是紧急事务,必须立即处理,我想不出有任何理由推迟中断的处理。

论坛徽章:
0
4 [报告]
发表于 2007-06-28 10:42 |显示全部楼层
原帖由 Solaris12 于 2007-6-27 20:25 发表于 17楼  


Cool!

你说的很准确。的确是你说的情况。

举例来说, 写网卡驱动程序,我们通常把中断服务函数说成ISR。

但在Solaris里,每个级低优先级中断都有个IST,中断服务线程。


我说的ISR是驱动程序的 ...

看来Solaris中的IST有点类似用内核线程来实现中断的handler,这种情况下应该是可以睡眠的。
Solaris的实现果然和linux有很多不同,要多多请教了。

论坛徽章:
0
5 [报告]
发表于 2007-06-28 10:56 |显示全部楼层
原帖由 xiaozhaoz 于 2007-6-27 22:36 发表于 21楼  


简单看了一下前面的回复, 不能认同.

问题的焦点大家都集中在异步异常(中断)没有自己的上下文?

中断抢占了当前任务后, 可以通过current获得当前的task结构, 将当前任务的寄存器信息压入栈中, 替换成自 ...

此外,我想lz对上下文一词还有点误解。
上下文(context)表示当前cpu的状态,包括各种标志及寄存器的值。这里中断是运行在自己的上下文而不是进程的上下文。如果是运行在进程上下文的话,中断处理就不需要在开始就保存上下文,在离开的时候又恢复。
当然,有一些先进的处理器(例如安腾),它为中断处理程序提供了一套专门的寄存器供中断处理程序使用,这个时候很多上下文是不需要保存的(但并非说就不保存上下文,只是某些不用保存)

论坛徽章:
0
6 [报告]
发表于 2007-06-28 10:58 |显示全部楼层
原帖由 xiaozhaoz 于 2007-6-27 23:13 发表于 23楼  


所见略同.

19楼描述的就是这个问题.

而realtime Patch解决的也是这个问题.

PS. 最近在做一个多内核的项目, 包括solaris, 请问你们讨论solaris内核一般在哪里? OpenSolaris的mail list感觉不太热闹.

OpenSolaris?阁下是intel的?或是SUN北京分舵的?
如果不是,国内也有公司开始做OpenSolaris了?

论坛徽章:
0
7 [报告]
发表于 2007-06-28 11:15 |显示全部楼层
原帖由 思一克 于 2007-6-28 11:05 发表于 31楼  
中断当然有自己的CONTEXT。但没有(准确说经常没有)进程相关的CONTEXT。
你看2.6.13 KERNEL,IRQ使用 自己的STACK,如果在中断中schedule()了,能正确回来吗?



不好意思,我看贴也不仔细,把lz“总结:
    异步异常(中断)handler不是没有上下文, 而是没有固定的上下文,  如果使用被抢占的任务作为上下文, 一,自身的处理无法得到实时保障,导致系统不确定性, 二,任务受到影响.”这句话看成中断使用进程上下文了。

论坛徽章:
0
8 [报告]
发表于 2007-06-28 11:25 |显示全部楼层
原帖由 xiaozhaoz 于 2007-6-28 11:13 发表于 32楼  


中断sleep了, 由谁来唤醒?
在关中断的情况下, 不能sleep, 19楼已经描述了.
在中断handler中, 绝大部分都是开中断的, 这个时候为什么不能sleep? 时钟中断可以正常触发, 要不中断嵌套怎么实现? 当然由时钟中 ...

>>在中断handler中, 绝大部分都是开中断的, 这个时候为什么不能sleep? 时钟中断可以正常触发, 要不中断嵌套怎么实现? 当然由时钟中断的软中断来唤醒. 如我说到的:
如果内核修改好了, handler中调用schedule_timeout_interrupt().的情况.
当然,如果你把handler用内核进程来实现,当然是可以睡眠和被调度的。这只是个实现问题。我这里的指的是linux下不能睡眠的原因。


>>中断都很紧急, 这不一定正确,
紧急是个相对概念,我认为中断都比进程紧急

论坛徽章:
0
9 [报告]
发表于 2007-06-28 12:38 |显示全部楼层
原帖由 xiaozhaoz 于 2007-6-28 12:19 发表于 39楼  


对, 就是这个意思,
所以这种系统的不确定性就很大.  
而现在的中断除了不sleep, 不能preempt之外, 对任务的影响也想你说的那样"中奖"式的, 所以现在系统的实时性是无法保证的!!

解决这个问 ...

>>总结: 异步异常(中断)handler不是没有上下文, 而是没有固定的上下文,  如果使用被抢占的任务作为上下文, 一,自身的处理无法得到实时保障,导致系统不确定性, 二,任务受到影响.

linux是通用操作系统,并不是专门为嵌入式设计的实时操作系统,所以影响系统的实时性并不是中断不能睡眠的原因。
诚然,中断不像进程那样有固定的上下文,所以它在linux中不是调度器的调度单位,所以不能睡眠,因为睡眠、唤醒都是调度器的任务,你不被调度器调度,当然不能睡眠。如你所说,它是可以被实现成可睡眠的,但我这里讲述的是它在linux中不能睡眠的原因。如果我的理解还不对的话,请lz再用一句总结一下在linux中中断不能睡眠的原因。因为你文字比较多,我看的有点乱了。

[ 本帖最后由 zx_wing 于 2007-6-28 12:39 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2007-06-28 13:59 |显示全部楼层
原帖由 思一克 于 2007-6-28 13:16 发表于 41楼  
LZ发帖子是讨论,不是有什么总结性的一句话能概括什么。我也是在学习中。

我觉得,LINUX设计不让中断中睡眠是经过充分考虑的。seelp on interrupt(SOI)不允许是内核设计的原因,而不是有什么绝对本质的无法 ...

我说的lz是xiaozhaoz兄,因为他概括的观点有点多,我看的不是很明白,所以想让他总结一下。
呵呵,版主以为我在叫你啦
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP