- 论坛徽章:
- 0
|
LZ发帖子是讨论,不是有什么总结性的一句话能概括什么。我也是在学习中。
我觉得,LINUX设计不让中断中睡眠是经过充分考虑的。seelp on interrupt(SOI)不允许是内核设计的原因,而不是有什么绝对本质的无法更改的原因。
我同意zx_wing的说法,没有和进程关联的CONTEXT,而调度的基本单位是进程,因此KERNEL设计者无法容忍sleep on interrrupt(SOI).
下面的相同的讨论说的也很清楚:
think this should clear all confusions, apologies if this is too big
or irrelevant and doesnt make much sense, which I think is not the
case.
Note : The following explaination assumes that the isr and the
interrupted proceess share the stack, afaik isr can seperate stacks,
which is configurable, but I dont know how this explaination holds
good when the isr is having a seperate stack.
1. Why you are not allowed to sleep in an interrupt handler?Was this a
design decision or is there a fundamental reason that makes sleeping
interrupt handlers simply impossible? What about the page fault
handler - it (probably) sleeps when it has to swap in a page, why is
it possible to sleep for the page fault handler and not for an
interrupt handler?
-> Sleeping is implemented using scheduler. Scheduler only schedules
tasks (design decision to keep it simple). So you need a task context
to sleep in. Interrupt is not tied to a process (and uses stack of
whichever happens to be scheduled ) so it can't use the context
because it does not have to be in a sane state.
2. But why.....
You cannot sleep in an interrupt handler because interrupts do not have
a backing process context, and thus there is nothing to reschedule
back into. In other words, interrupt handlers are not associated with
a task, so there is nothing to "put to sleep" and (more importantly)
"nothing to wake up". They must run atomically.
The reason the page fault handler can sleep is that it is invoked only
by code that is running in process context. Because the kernel's own
memory is not pagable, only user-space memory accesses can result in a
page fault. Thus, only a few certain places (such as calls to
copy_{to,from}_user()) can cause a page fault within the kernel. Those
places must all be made by code that can sleep (i.e., process context,
no locks, etc).
3. However can't you consider the interrupt handler as running in the
context of the task A, that was incidentially running when the
interrupt occurred (the interrupt handler
uses the stack of task A, this is not always true, isr might have a
seperate stack). So wouldn't it conceptually be conceivable to put the
interrupt handler to sleep by saving the current CPU state (register
contents) with task A, putting task A asleep, and resume processing of
the interrupt once task A is rescheduled by the scheduler?
Of course this could be considered 'unfair' with respect to task A, in
that the interrupt has no relation to task A besides the fact that
they happend to be on the same CPU at the same time. But I am
interested in learning if there is any fundamental reason against
sleeping in an interrupt handler.
->There are bigger problems. The process is in an arbitrary state when
interrupt is invoked. So it might hold arbitrary spinlocks. It might
be on arbitrary wait_queues. Possibly other funny things might happen.
These either disallow sleeping or could interact badly with the
interrupt trying to sleep.
This is part of conversation happened on the same list before few
years, not verbatim though.
--
这里也说到了如果IRQ不用自己的STACK,而利用被中断任务(任务A)的STACK是否就可以SOI了的问题。
因为中断发生的CONTEXT和A无关,而是碰巧在同一个CPU上的一个任务A被中断了,如果中断睡了,A就回被殃及,系统就彻底乱了。
(和调度发生冲突了)。
至于schedule()会将任务在不同CPU之间分,而IRQ回来后如何?(假定IRQ不使用自己的STACK,可以回来的话)。
还有最后一段说的其他各种复杂的问题。
总之,如果中断不THREAD化,应该无法SOI。所以LINUX(2。6)中shedule()中有检查不允许。
如果改动LINUX,如何改动最小使得可以SOI?(虽然没有大意义,但作为讨论可以从讨论中学习其他的)。
原帖由 zx_wing 于 2007-6-28 12:38 发表于 40楼
>>总结: 异步异常(中断)handler不是没有上下文, 而是没有固定的上下文, 如果使用被抢占的任务作为上下文, 一,自身的处理无法得到实时保障,导致系统不确定性, 二,任务受到影响.
linux是通用操作系统 ... |
|