# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1225104225 0
# Node ID 9750ab8d7faa8a9503810d38fa4c072f57163b68
# Parent 2b1dc4b1b23168227806e3d1facc26f814b25764
Fix IRQ-from-evtchn delivery so that softirq handling does not happen
while IRQ delivery is blocked. We do this by moving irq_enter/irq_exit
outside the mutual-exclusion region in evtchn_do_upcall(). We then
have to remove irq_enter/irq_exit from do_IRQ(), otherwise the
preempt_coutn check in the rcu code will always fail and we hang
during boot.
Thanks to Eduard Guzovsky of Stratus for help with this patch.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
arch/i386/kernel/irq-xen.c | 4 ++--
arch/x86_64/kernel/irq-xen.c | 6 +++---
drivers/xen/core/evtchn.c | 10 ++++++----
include/asm-ia64/hypercall.h | 6 +-----
4 files changed, 12 insertions(+), 14 deletions(-)
diff -r 2b1dc4b1b231 -r 9750ab8d7faa arch/i386/kernel/irq-xen.c
--- a/arch/i386/kernel/irq-xen.c Mon Oct 27 10:32:08 2008 +0000
+++ b/arch/i386/kernel/irq-xen.c Mon Oct 27 10:43:45 2008 +0000
@@ -66,7 +66,7 @@ fastcall unsigned int do_IRQ(struct pt_r
BUG();
}
- irq_enter();
+ /*irq_enter();*/
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 1KB free? */
{
@@ -121,7 +121,7 @@ fastcall unsigned int do_IRQ(struct pt_r
#endif
__do_IRQ(irq, regs);
- irq_exit();
+ /*irq_exit();*/
return 1;
}
diff -r 2b1dc4b1b231 -r 9750ab8d7faa arch/x86_64/kernel/irq-xen.c
--- a/arch/x86_64/kernel/irq-xen.c Mon Oct 27 10:32:08 2008 +0000
+++ b/arch/x86_64/kernel/irq-xen.c Mon Oct 27 10:43:45 2008 +0000
@@ -124,13 +124,13 @@ asmlinkage unsigned int do_IRQ(struct pt
BUG();
}
- exit_idle();
- irq_enter();
+ /*exit_idle();*/
+ /*irq_enter();*/
#ifdef CONFIG_DEBUG_STACKOVERFLOW
stack_overflow_check(regs);
#endif
__do_IRQ(irq, regs);
- irq_exit();
+ /*irq_exit();*/
return 1;
}
diff -r 2b1dc4b1b231 -r 9750ab8d7faa drivers/xen/core/evtchn.c
--- a/drivers/xen/core/evtchn.c Mon Oct 27 10:32:08 2008 +0000
+++ b/drivers/xen/core/evtchn.c Mon Oct 27 10:43:45 2008 +0000
@@ -246,6 +246,8 @@ asmlinkage void evtchn_do_upcall(struct
shared_info_t *s = HYPERVISOR_shared_info;
vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
+ exit_idle();
+ irq_enter();
do {
/* Avoid a callback storm when we reenable delivery. */
@@ -253,7 +255,7 @@ asmlinkage void evtchn_do_upcall(struct
/* Nested invocations bail immediately. */
if (unlikely(per_cpu(upcall_count, cpu)++))
- return;
+ break;
#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
/* Clear master flag /before/ clearing selector flag. */
@@ -293,10 +295,8 @@ asmlinkage void evtchn_do_upcall(struct
port = (l1i * BITS_PER_LONG) + l2i;
if ((irq = evtchn_to_irq[port]) != -1)
do_IRQ(irq, regs);
- else {
- exit_idle();
+ else
evtchn_device_upcall(port);
- }
/* if this is the final port processed, we'll
pick up here+1 next time */
per_cpu(last_processed_l1i, cpu) = l1i;
@@ -314,6 +314,8 @@ asmlinkage void evtchn_do_upcall(struct
count = per_cpu(upcall_count, cpu);
per_cpu(upcall_count, cpu) = 0;
} while (unlikely(count != 1));
+
+ irq_exit();
}
static int find_unbound_irq(void)
diff -r 2b1dc4b1b231 -r 9750ab8d7faa include/asm-ia64/hypercall.h
--- a/include/asm-ia64/hypercall.h Mon Oct 27 10:32:08 2008 +0000
+++ b/include/asm-ia64/hypercall.h Mon Oct 27 10:43:45 2008 +0000
@@ -237,11 +237,7 @@ xencomm_arch_hypercall_opt_feature(struc
extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
static inline void exit_idle(void) {}
-#define do_IRQ(irq, regs) ({ \
- irq_enter(); \
- __do_IRQ((irq), (regs)); \
- irq_exit(); \
-})
+#define do_IRQ(irq, regs) __do_IRQ((irq), (regs))
#include <linux/err.h>
#ifdef HAVE_XEN_PLATFORM_COMPAT_H
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|