aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2009-02-06 17:09:46 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-09 06:18:09 -0500
commit3445a8fd7c6868bd9db0d1bea7d6e89004552122 (patch)
treee702ab02c72392cda5ee80e8cc12db60e2b0f271 /drivers/xen
parentd77bbd4db475e2edc78edb7f94a258159c140b54 (diff)
xen: make sure that softirqs get handled at the end of event processing
Make sure that irq_enter()/irq_exit() wrap the entire event processing loop, rather than each individual event invokation. This makes sure that softirq processing is deferred until the end of event processing, rather than in the middle with interrupts disabled. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/events.c29
1 files changed, 9 insertions, 20 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 459121c53251..e53fd60fe4b8 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -595,25 +595,6 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
595 return IRQ_HANDLED; 595 return IRQ_HANDLED;
596} 596}
597 597
598
599static void xen_do_irq(unsigned irq, struct pt_regs *regs)
600{
601 struct pt_regs *old_regs = set_irq_regs(regs);
602
603 if (WARN_ON(irq == -1))
604 return;
605
606 exit_idle();
607 irq_enter();
608
609 //printk("cpu %d handling irq %d\n", smp_processor_id(), info->irq);
610 handle_irq(irq, regs);
611
612 irq_exit();
613
614 set_irq_regs(old_regs);
615}
616
617/* 598/*
618 * Search the CPUs pending events bitmasks. For each one found, map 599 * Search the CPUs pending events bitmasks. For each one found, map
619 * the event number to an irq, and feed it into do_IRQ() for 600 * the event number to an irq, and feed it into do_IRQ() for
@@ -626,11 +607,15 @@ static void xen_do_irq(unsigned irq, struct pt_regs *regs)
626void xen_evtchn_do_upcall(struct pt_regs *regs) 607void xen_evtchn_do_upcall(struct pt_regs *regs)
627{ 608{
628 int cpu = get_cpu(); 609 int cpu = get_cpu();
610 struct pt_regs *old_regs = set_irq_regs(regs);
629 struct shared_info *s = HYPERVISOR_shared_info; 611 struct shared_info *s = HYPERVISOR_shared_info;
630 struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu); 612 struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
631 static DEFINE_PER_CPU(unsigned, nesting_count); 613 static DEFINE_PER_CPU(unsigned, nesting_count);
632 unsigned count; 614 unsigned count;
633 615
616 exit_idle();
617 irq_enter();
618
634 do { 619 do {
635 unsigned long pending_words; 620 unsigned long pending_words;
636 621
@@ -654,7 +639,8 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
654 int port = (word_idx * BITS_PER_LONG) + bit_idx; 639 int port = (word_idx * BITS_PER_LONG) + bit_idx;
655 int irq = evtchn_to_irq[port]; 640 int irq = evtchn_to_irq[port];
656 641
657 xen_do_irq(irq, regs); 642 if (irq != -1)
643 handle_irq(irq, regs);
658 } 644 }
659 } 645 }
660 646
@@ -665,6 +651,9 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
665 } while(count != 1); 651 } while(count != 1);
666 652
667out: 653out:
654 irq_exit();
655 set_irq_regs(old_regs);
656
668 put_cpu(); 657 put_cpu();
669} 658}
670 659