# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1264751868 0
# Node ID c88a02a22a057a632e6c21442e42e56e07904988
# Parent 91224343eeee460c9aafdaadc1bdedab54e92256
xen/evtchn: Clean up round-robin evtchn scan.
Also fixes a couple of boundary cases.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
drivers/xen/core/evtchn.c | 45 +++++++++++++++++++++------------------------
1 files changed, 21 insertions(+), 24 deletions(-)
diff -r 91224343eeee -r c88a02a22a05 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 Fri Jan 29 07:57:48 2010 +0000
@@ -229,9 +229,9 @@ void force_evtchn_callback(void)
/* Not a GPL symbol: used in ubiquitous macros, so too restrictive. */
EXPORT_SYMBOL(force_evtchn_callback);
-static DEFINE_PER_CPU(unsigned int, upcall_count) = { 0 };
-static DEFINE_PER_CPU(unsigned int, last_processed_l1i) = { BITS_PER_LONG - 1
};
-static DEFINE_PER_CPU(unsigned int, last_processed_l2i) = { BITS_PER_LONG - 1
};
+static DEFINE_PER_CPU(unsigned int, upcall_count);
+static DEFINE_PER_CPU(unsigned int, current_l1i);
+static DEFINE_PER_CPU(unsigned int, current_l2i);
/* NB. Interrupts are disabled on entry. */
asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
@@ -261,32 +261,23 @@ asmlinkage void evtchn_do_upcall(struct
#endif
l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
- l1i = per_cpu(last_processed_l1i, cpu);
- l2i = per_cpu(last_processed_l2i, cpu);
+ l1i = per_cpu(current_l1i, cpu);
+ l2i = per_cpu(current_l2i, cpu);
while (l1 != 0) {
-
- 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;
+ /* If we masked out all events, wrap to beginning. */
+ if (masked_l1 == 0) {
+ l1i = l2i = 0;
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;
+ if (masked_l2 == 0)
break;
- }
-
l2i = __ffs(masked_l2);
/* process port */
@@ -296,16 +287,22 @@ asmlinkage void evtchn_do_upcall(struct
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;
- per_cpu(last_processed_l2i, cpu) = l2i;
-
- } while (l2i != BITS_PER_LONG - 1);
+ l2i = (l2i + 1) % BITS_PER_LONG;
+
+ /* Next caller starts at last processed + 1 */
+ per_cpu(current_l1i, cpu) =
+ l2i ? l1i : (l1i + 1) % BITS_PER_LONG;
+ per_cpu(current_l2i, cpu) = l2i;
+
+ } while (l2i != 0);
l2 = active_evtchns(cpu, s, l1i);
- if (l2 == 0) /* we handled all ports, so we can clear
the selector bit */
+ /* If we handled all ports, clear the selector bit. */
+ if (l2 == 0)
l1 &= ~(1UL << l1i);
+ l1i = (l1i + 1) % BITS_PER_LONG;
+ l2i = 0;
}
/* If there were nested callbacks then we have more to do. */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|