[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] evtchn_do_upcall: search a snapshot of level 2 bits for pending upcalls
# HG changeset patch # User kaushik # Date 1264744731 21600 # Node ID 12c3dcae53baf45665266614d4b589875c819355 # Parent 91224343eeee460c9aafdaadc1bdedab54e92256 Search a snapshot of level 2 bits for pending upcalls. Using only a snapshot of level 1 bits can lead to unfairness in some cases. Consider the case where two upcalls are marked pending after a snapshot of level 1 bits is taken. One of these two upcalls can still be processed if the corresponding level 1 bit was already set. This is not a perfect solution since its still possible for a level 2 bit to be set before a level 2 snapshot is taken (unless both snapshots are taken atomically). Signed-off-by: Kaushik Kumar Ram <kaushik@xxxxxxxx> diff -r 91224343eeee -r 12c3dcae53ba drivers/xen/core/evtchn.c --- a/drivers/xen/core/evtchn.c Thu Jan 21 15:05:02 2010 +0000 +++ b/drivers/xen/core/evtchn.c Thu Jan 28 23:58:51 2010 -0600 @@ -243,6 +243,8 @@ asmlinkage void evtchn_do_upcall(struct unsigned int cpu = smp_processor_id(); shared_info_t *s = HYPERVISOR_shared_info; vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; + int i; + unsigned long local_l2[sizeof(unsigned long) * 8]; exit_idle(); irq_enter(); @@ -260,6 +262,10 @@ asmlinkage void evtchn_do_upcall(struct wmb(); #endif l1 = xchg(&vcpu_info->evtchn_pending_sel, 0); + + for(i = 0; i < BITS_PER_LONG; i++) { + local_l2[i] = active_evtchns(cpu, s, i); + } l1i = per_cpu(last_processed_l1i, cpu); l2i = per_cpu(last_processed_l2i, cpu); @@ -277,7 +283,7 @@ asmlinkage void evtchn_do_upcall(struct l1i = __ffs(masked_l1); do { - l2 = active_evtchns(cpu, s, l1i); + l2 = local_l2[l1i]; l2i = (l2i + 1) % BITS_PER_LONG; masked_l2 = l2 & ((~0UL) << l2i); @@ -296,13 +302,15 @@ asmlinkage void evtchn_do_upcall(struct else evtchn_device_upcall(port); + clear_bit(l2i, &local_l2[l1i]); + /* if this is the final port processed, we'll pick up here+1 next time */ per_cpu(last_processed_l1i, cpu) = l1i; per_cpu(last_processed_l2i, cpu) = l2i; } while (l2i != BITS_PER_LONG - 1); - l2 = active_evtchns(cpu, s, l1i); + l2 = local_l2[l1i]; if (l2 == 0) /* we handled all ports, so we can clear the selector bit */ l1 &= ~(1UL << l1i); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |