[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] Process event channels notifications in round-robin order.
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxx> # Date 1196433331 0 # Node ID 7fe1c6d02a2bd8d38b6a8b529f166990e4cd1dc3 # Parent fd879c0688bf123a85dcfa371f863da3542ab8af Process event channels notifications in round-robin order. Avoids fairness issue resulting from domain 0 processing lowest numbered event channel first. Bugzilla #1115 "Event channel port scanning unfair". From: Scott Rixner <rixner@xxxxxxxx> From: Diego Ongaro <dieo.ongaro@xxxxxxxx> From: Alan L. Cox <alc@xxxxxxxx> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx> --- drivers/xen/core/evtchn.c | 60 ++++++++++++++++++++++++++++++++++++---------- 1 files changed, 48 insertions(+), 12 deletions(-) diff -r fd879c0688bf -r 7fe1c6d02a2b drivers/xen/core/evtchn.c --- a/drivers/xen/core/evtchn.c Fri Nov 23 16:26:56 2007 +0000 +++ b/drivers/xen/core/evtchn.c Fri Nov 30 14:35:31 2007 +0000 @@ -225,11 +225,14 @@ static DEFINE_PER_CPU(unsigned int, upca /* NB. Interrupts are disabled on entry. */ asmlinkage void evtchn_do_upcall(struct pt_regs *regs) { - unsigned long l1, l2; - unsigned int l1i, l2i, port, count; - int irq, cpu = smp_processor_id(); - shared_info_t *s = HYPERVISOR_shared_info; - vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; + unsigned long l1, l2; + unsigned long masked_l1, masked_l2; + unsigned int l1i, l2i, port, count; + static unsigned int last_processed_l1i = BITS_PER_LONG - 1, last_processed_l2i = BITS_PER_LONG - 1; + int irq, cpu = smp_processor_id(); + shared_info_t *s = HYPERVISOR_shared_info; + vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; + do { /* Avoid a callback storm when we reenable delivery. */ @@ -244,13 +247,36 @@ asmlinkage void evtchn_do_upcall(struct rmb(); #endif l1 = xchg(&vcpu_info->evtchn_pending_sel, 0); + + l1i = last_processed_l1i; + l2i = last_processed_l2i; + while (l1 != 0) { - l1i = __ffs(l1); - l1 &= ~(1UL << l1i); - - while ((l2 = active_evtchns(cpu, s, l1i)) != 0) { - l2i = __ffs(l2); - + + l1i = (l1i + 1) % BITS_PER_LONG; + masked_l1 = l1 & ((~0UL) << l1i); + + if (masked_l1 == 0) { /* if we masked out all events, wrap around to the beginning */ + l1i = BITS_PER_LONG - 1; + l2i = BITS_PER_LONG - 1; + continue; + } + l1i = __ffs(masked_l1); + + do { + l2 = active_evtchns(cpu, s, l1i); + + l2i = (l2i + 1) % BITS_PER_LONG; + masked_l2 = l2 & ((~0UL) << l2i); + + if (masked_l2 == 0) { /* if we masked out all events, move on */ + l2i = BITS_PER_LONG - 1; + break; + } + + l2i = __ffs(masked_l2); + + /* process port */ port = (l1i * BITS_PER_LONG) + l2i; if ((irq = evtchn_to_irq[port]) != -1) do_IRQ(irq, regs); @@ -258,7 +284,17 @@ asmlinkage void evtchn_do_upcall(struct exit_idle(); evtchn_device_upcall(port); } - } + + /* if this is the final port processed, we'll pick up here+1 next time */ + last_processed_l1i = l1i; + last_processed_l2i = l2i; + + } while (l2i != BITS_PER_LONG - 1); + + l2 = active_evtchns(cpu, s, l1i); + if (l2 == 0) /* we handled all ports, so we can clear the selector bit */ + l1 &= ~(1UL << l1i); + } /* If there were nested callbacks then we have more to do. */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog |
Lists.xenproject.org is hosted with RackSpace, monitoring our |