[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] Fix IRQ-from-evtchn delivery so that softirq handling does not happen



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.