aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2011-03-03 06:06:28 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-03-10 14:47:58 -0500
commit24b51c2f2de019a4596415e7bb1e92711127d0e0 (patch)
tree4cfef59033541c67f7e96bffcfadef135f85f666 /drivers/xen
parentada6814c878c4d95fc8ca1402e49effbf3cc319a (diff)
xen: events: Make round-robin scan fairer by snapshotting each l2 word once only
(except for starting l2 word, which we scan in two parts). Signed-off-by: Keir Fraser <keir.fraser@citrix.com> Signed-off-by: Ian Campbell <ian.campbell@citrix.com> [ijc: forward ported from linux-2.6.18-xen.hg 990:427276ac595d] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/events.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index c49cb6d6b838..0c3f17ba3956 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -1045,7 +1045,9 @@ static DEFINE_PER_CPU(unsigned int, current_bit_idx);
1045 */ 1045 */
1046static void __xen_evtchn_do_upcall(void) 1046static void __xen_evtchn_do_upcall(void)
1047{ 1047{
1048 int start_word_idx, start_bit_idx;
1048 int word_idx, bit_idx; 1049 int word_idx, bit_idx;
1050 int i;
1049 int cpu = get_cpu(); 1051 int cpu = get_cpu();
1050 struct shared_info *s = HYPERVISOR_shared_info; 1052 struct shared_info *s = HYPERVISOR_shared_info;
1051 struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); 1053 struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
@@ -1065,10 +1067,12 @@ static void __xen_evtchn_do_upcall(void)
1065#endif 1067#endif
1066 pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); 1068 pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
1067 1069
1068 word_idx = __this_cpu_read(current_word_idx); 1070 start_word_idx = __this_cpu_read(current_word_idx);
1069 bit_idx = __this_cpu_read(current_bit_idx); 1071 start_bit_idx = __this_cpu_read(current_bit_idx);
1072
1073 word_idx = start_word_idx;
1070 1074
1071 while (pending_words != 0) { 1075 for (i = 0; pending_words != 0; i++) {
1072 unsigned long pending_bits; 1076 unsigned long pending_bits;
1073 unsigned long words; 1077 unsigned long words;
1074 1078
@@ -1084,13 +1088,23 @@ static void __xen_evtchn_do_upcall(void)
1084 } 1088 }
1085 word_idx = __ffs(words); 1089 word_idx = __ffs(words);
1086 1090
1091 pending_bits = active_evtchns(cpu, s, word_idx);
1092 bit_idx = 0; /* usually scan entire word from start */
1093 if (word_idx == start_word_idx) {
1094 /* We scan the starting word in two parts */
1095 if (i == 0)
1096 /* 1st time: start in the middle */
1097 bit_idx = start_bit_idx;
1098 else
1099 /* 2nd time: mask bits done already */
1100 bit_idx &= (1UL << start_bit_idx) - 1;
1101 }
1102
1087 do { 1103 do {
1088 unsigned long bits; 1104 unsigned long bits;
1089 int port, irq; 1105 int port, irq;
1090 struct irq_desc *desc; 1106 struct irq_desc *desc;
1091 1107
1092 pending_bits = active_evtchns(cpu, s, word_idx);
1093
1094 bits = MASK_LSBS(pending_bits, bit_idx); 1108 bits = MASK_LSBS(pending_bits, bit_idx);
1095 1109
1096 /* If we masked out all events, move on. */ 1110 /* If we masked out all events, move on. */
@@ -1121,10 +1135,8 @@ static void __xen_evtchn_do_upcall(void)
1121 __this_cpu_write(current_bit_idx, bit_idx); 1135 __this_cpu_write(current_bit_idx, bit_idx);
1122 } while (bit_idx != 0); 1136 } while (bit_idx != 0);
1123 1137
1124 pending_bits = active_evtchns(cpu, s, word_idx); 1138 /* Scan start_l1i twice; all others once. */
1125 1139 if ((word_idx != start_word_idx) || (i != 0))
1126 /* If we handled all ports, clear the selector bit. */
1127 if (pending_bits == 0)
1128 pending_words &= ~(1UL << word_idx); 1140 pending_words &= ~(1UL << word_idx);
1129 1141
1130 word_idx = (word_idx + 1) % BITS_PER_LONG; 1142 word_idx = (word_idx + 1) % BITS_PER_LONG;