- 论坛徽章:
- 0
|
ovis_poly
(member)
09-07-26 22:10
![]()
Re: 异常能睡,中断睡不得? [
re: wheelz
]
![]()
回复
我也一直没有得到这个问题的满意答案,仔细阅读了楼上各位的帖子觉得非常有帮助,这个问题经典的回答就是robert love的说法,中断没有自己的上下文,但这句话是从1万英尺上空回答的,没有错误,但还是无法让人觉得豁然开朗。假如我就是要在irq中sleep,到底会发生什么呢?没有上下文,Linux就完全懵了么?
因为无论如何中断发生时也必然有一个当前的进程,在irq中睡眠的结果就是将这个无辜的进程插入等待队列。但我想既然irq当时决定睡眠,那么就一定有另外一个内核线程,或者进程会最终唤醒irq,那么无辜进程便有机会重新得到执行。这种情况下,某个进程只是被无辜的suspend了一段时间,其余我觉得没有什么严重的事情发生。
或者在某种情况下,无辜进程正好就是那个打算唤醒irq的进程,由于其在睡眠,便永远不可能被唤醒了,发生了死锁,此外,我想不出其他的原因。
中断线程化是Linux实时补丁中的重要技术,每个irq都对应一个独立的内核线程,所以可以参与调度,自然便也可以睡眠了。
当然在irq中睡眠是一个毫无必要的需求,可以使用workqueue。
一点拙见,楼上讨论的已经非常清楚,我只是再插一句 ;-)
文章选项:
![]()
![]()
![]()
![]()
yjfpb04
(enthusiast)
09-07-27 09:36
![]()
Re: 异常能睡,中断睡不得? [
re: wxc200
]
![]()
回复
技术角度讲,中断中可以睡眠的,也可以切换。
但
1.可能会造成死锁
2.本来中断打断了别人,应该尽快返回,如果又切换到别的进程的话,不符合设计的初衷。
3.中断栈的情况下,如果中断处理睡眠了,那么就无法调度回来了
--------------------
蛋蛋..
文章选项:
![]()
![]()
![]()
![]()
wxc200
(enthusiast)
09-07-27 11:55
![]()
Re: 异常能睡,中断睡不得? [
re: ovis_poly
]
![]()
编辑
![]()
回复
我也一直没有得到这个问题的满意答案,仔细阅读了楼上各位的帖子觉得非常有帮助,这个问题经典的回答就是robert love的说法,中断没有自己的上下文,但这句话是从1万英尺上空回答的,没有错误,但还是无法让人觉得豁然开朗。假如我就是要在irq中sleep,到底会发生什么呢?没有上下文,Linux就完全懵了么?
因为无论如何中断发生时也必然有一个当前的进程,在irq中睡眠的结果就是将这个无辜的进程插入等待队列。但我想既然irq当时决定睡眠,那么就一定有另外一个内核线程,或者进程会最终唤醒irq,那么无辜进程便有机会重新得到执行。这种情况下,某个进程只是被无辜的suspend了一段时间,其余我觉得没有什么严重的事情发生。
>> 这个地方就是“能不能睡下去”和“能不能唤醒”的问题。要sleep的irq 环境是一个与当前进程不相干的特殊环境,在进入此环境之前已经与当前进程的环境做了处理(比如把current task的环境保存等),那么此时要睡眠,调度器要进行prev/next的context切换,问题就在这儿,它知道当前的环境是中断么? 知道的话会做特殊处理么(比如选取current已经保存 的环境做为要调度的context)? 所以尽管current还存在,但当前运行着的环境是与进程不相关的。而这个环境kernel不把它作为一种参与调度的环境对待.这势必造成后面的“唤醒”问题----中断这个特殊环境难以恢复了。
或者在某种情况下,无辜进程正好就是那个打算唤醒irq的进程,由于其在睡眠,便永远不可能被唤醒了,发生了死锁,此外,我想不出其他的原因。
中断线程化是Linux实时补丁中的重要技术,每个irq都对应一个独立的内核线程,所以可以参与调度,自然便也可以睡眠了。
当然在irq中睡眠是一个毫无必要的需求,可以使用workqueue。
>>我在题目里问得是睡,应该是“进程切换”更确切。sleep会把进程移出run queue,而”进程切换“让其仍在run queue,在“非外部唤醒”的情况下也有可以调度到它。这样虽避免了上述死锁问题,但还是如前面说的,无法恢复中断这种比较特殊的环境了.
--------------------
一杯绿茶,一颗香烟
文章选项:
![]()
![]()
![]()
![]()
shiweixingcn
(stranger)
09-08-02 12:23
![]()
Re: 异常能睡,中断睡不得? [
re: wxc200
]
![]()
回复
我觉得最关键的是看硬件怎么处理中断和缺页异常,中断进来了,状态寄存器的中断使能位就关了,其他中断进不来,这时候,你就没有调度点了,我不知道异常过来后,是不是也关了中断使能位,我猜测是没有关的,所以其他中断可以过来,因此有调度点。
文章选项:
![]()
![]()
![]()
![]()
wxc200
(enthusiast)
09-08-02 15:16
![]()
Re: 异常能睡,中断睡不得? [
re: shiweixingcn
]
![]()
编辑
![]()
回复
我觉得最关键的是看硬件怎么处理中断和缺页异常,中断进来了,状态寄存器的中断使能位就关了,其他中断进不来,这时候,你就没有调度点了,
>>中断处理有一些临界区是禁中断,但随即会打开。整个中断处理中会有中断嵌套的情况。
我不知道异常过来后,是不是也关了中断使能位,我猜测是没有关的,所以其他中断可以过来,因此有调度点。
>>异常可以被中断打断,也可以调度,不会操作中断使能位
--------------------
一杯绿茶,一颗香烟
文章选项:
![]()
![]()
![]()
![]()
shiweixingcn
(stranger)
09-08-02 22:12
![]()
Re: 异常能睡,中断睡不得? [
re: wxc200
]
![]()
回复
我是指硬件上是怎么处理的,从x86的文档来看,外部中断走的是interrupt gate,而缺页异常走的是trap gate,硬件上这两个gate处理最大的不同在于对于eflage的IF位的处理不同,interrupt gate是要置1,而trap gate什么也不做,也就是说,interrupt过来后,cpu就不能相应其他中断。
另外关于栈的问题,只要进了内核空间,用的都应该都是内核栈,版上有些人说用的是current的栈,我觉得似乎有问题,因为只要用户空间向内核空间切换,x86规定硬件要做栈切换的,而相同的优先级(比如task switch或者是缺页然后发生中断)是不做栈切换的,所以缺页异常和外部中断应该用的是相同内核栈空间。
文章选项:
![]()
![]()
![]()
![]()
原帖子:
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxK&Number=726647&page=&view=&sb=&o=&fpart=2&vc=1
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/110888/showart_2159411.html |
|