aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/events.c44
1 files changed, 20 insertions, 24 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 1fc3192468ef..c49cb6d6b838 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -1026,8 +1026,8 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
1026} 1026}
1027 1027
1028static DEFINE_PER_CPU(unsigned, xed_nesting_count); 1028static DEFINE_PER_CPU(unsigned, xed_nesting_count);
1029static DEFINE_PER_CPU(unsigned int, last_word_idx) = { BITS_PER_LONG - 1 }; 1029static DEFINE_PER_CPU(unsigned int, current_word_idx);
1030static DEFINE_PER_CPU(unsigned int, last_bit_idx) = { BITS_PER_LONG - 1 }; 1030static DEFINE_PER_CPU(unsigned int, current_bit_idx);
1031 1031
1032/* 1032/*
1033 * Mask out the i least significant bits of w 1033 * Mask out the i least significant bits of w
@@ -1065,23 +1065,21 @@ static void __xen_evtchn_do_upcall(void)
1065#endif 1065#endif
1066 pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); 1066 pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
1067 1067
1068 word_idx = __this_cpu_read(last_word_idx); 1068 word_idx = __this_cpu_read(current_word_idx);
1069 bit_idx = __this_cpu_read(last_bit_idx); 1069 bit_idx = __this_cpu_read(current_bit_idx);
1070 1070
1071 while (pending_words != 0) { 1071 while (pending_words != 0) {
1072 unsigned long pending_bits; 1072 unsigned long pending_bits;
1073 unsigned long words; 1073 unsigned long words;
1074 1074
1075 word_idx = (word_idx + 1) % BITS_PER_LONG;
1076 words = MASK_LSBS(pending_words, word_idx); 1075 words = MASK_LSBS(pending_words, word_idx);
1077 1076
1078 /* 1077 /*
1079 * If we masked out all events, wrap around to the 1078 * If we masked out all events, wrap to beginning.
1080 * beginning.
1081 */ 1079 */
1082 if (words == 0) { 1080 if (words == 0) {
1083 word_idx = BITS_PER_LONG - 1; 1081 word_idx = 0;
1084 bit_idx = BITS_PER_LONG - 1; 1082 bit_idx = 0;
1085 continue; 1083 continue;
1086 } 1084 }
1087 word_idx = __ffs(words); 1085 word_idx = __ffs(words);
@@ -1093,14 +1091,11 @@ static void __xen_evtchn_do_upcall(void)
1093 1091
1094 pending_bits = active_evtchns(cpu, s, word_idx); 1092 pending_bits = active_evtchns(cpu, s, word_idx);
1095 1093
1096 bit_idx = (bit_idx + 1) % BITS_PER_LONG;
1097 bits = MASK_LSBS(pending_bits, bit_idx); 1094 bits = MASK_LSBS(pending_bits, bit_idx);
1098 1095
1099 /* If we masked out all events, move on. */ 1096 /* If we masked out all events, move on. */
1100 if (bits == 0) { 1097 if (bits == 0)
1101 bit_idx = BITS_PER_LONG - 1;
1102 break; 1098 break;
1103 }
1104 1099
1105 bit_idx = __ffs(bits); 1100 bit_idx = __ffs(bits);
1106 1101
@@ -1117,22 +1112,23 @@ static void __xen_evtchn_do_upcall(void)
1117 generic_handle_irq_desc(irq, desc); 1112 generic_handle_irq_desc(irq, desc);
1118 } 1113 }
1119 1114
1120 /* 1115 bit_idx = (bit_idx + 1) % BITS_PER_LONG;
1121 * If this is the final port processed, we'll 1116
1122 * pick up here+1 next time. 1117 /* Next caller starts at last processed + 1 */
1123 */ 1118 __this_cpu_write(current_word_idx,
1124 __this_cpu_write(last_word_idx, word_idx); 1119 bit_idx ? word_idx :
1125 __this_cpu_write(last_bit_idx, bit_idx); 1120 (word_idx+1) % BITS_PER_LONG);
1126 } while (bit_idx != BITS_PER_LONG - 1); 1121 __this_cpu_write(current_bit_idx, bit_idx);
1122 } while (bit_idx != 0);
1127 1123
1128 pending_bits = active_evtchns(cpu, s, word_idx); 1124 pending_bits = active_evtchns(cpu, s, word_idx);
1129 1125
1130 /* 1126 /* If we handled all ports, clear the selector bit. */
1131 * We handled all ports, so we can clear the
1132 * selector bit.
1133 */
1134 if (pending_bits == 0) 1127 if (pending_bits == 0)
1135 pending_words &= ~(1UL << word_idx); 1128 pending_words &= ~(1UL << word_idx);
1129
1130 word_idx = (word_idx + 1) % BITS_PER_LONG;
1131 bit_idx = 0;
1136 } 1132 }
1137 1133
1138 BUG_ON(!irqs_disabled()); 1134 BUG_ON(!irqs_disabled());