- 论坛徽章:
- 0
|
omycle 发表于 2012-08-22 17:21 ![]()
回复 2# George_lz
根据代码提交意图,应该是针对所有的arch的,但这也与具体的使用有关。但具体是不是与具体的arch相关,也不敢肯定的这样说。由于我的开发环境是mips,以mips为例,在mips收到中断时,在保护现场时,disable mips 中断,然后就进入了plat 的irq dispatch,最后,进入了handle_irq,在handle_irq 里面进入driver所注册的handler。一般系统中断采用平出发,在2.6.34之前,在平触发的处理函数中,如果中断非独占,则会用(local_irq_enable_in_hardirq())打开mips中断,这样就允许中断嵌套。
在2.6.34之后,只是去掉了(local_irq_enable_in_hardirq()),一直不打开系统irq,直到irq执行结束。
kernel的平中断处理函数是系统通用代码,在这里修改,意图应该并不仅仅针对某个arch,应该是所有arch通用的。
此commit的描述如下:
commit e58aa3d2d0cc01ad8d6f7f640a0670433f794922
Author: Ingo Molnar <mingo@elte.hu>
Date: Fri Mar 26 00:06:51 2010 +0000
genirq: Run irq handlers with interrupts disabled
Running interrupt handlers with interrupts enabled can cause stack
overflows. That has been observed with multiqueue NICs delivering all
their interrupts to a single core. We might band aid that somehow by
checking the interrupt stacks, but the real safe fix is to run the irq
handlers with interrupts disabled.
Drivers for whacky hardware still can reenable them in the handler
itself, if the need arises. (They do already due to lockdep)
The risk of doing this is rather low:
- lockdep already enforces this
- CONFIG_NOHZ has shaken out the drivers which relied on jiffies updates
- time keeping is not longer sensitive to the timer interrupt being delayed
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Miller <davem@davemloft.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Linus Torvalds <torvalds@osdl.org>
LKML-Reference: <20100326000405.758579387@linutronix.de>
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 76d5a67..27e5c69 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -370,9 +370,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
irqreturn_t ret, retval = IRQ_NONE;
unsigned int status = 0;
- if (!(action->flags & IRQF_DISABLED))
- local_irq_enable_in_hardirq();
-
do {
trace_irq_handler_entry(irq, action);
ret = action->handler(irq, action->dev_id);
|
|