diff options
Diffstat (limited to 'drivers/xen/events.c')
-rw-r--r-- | drivers/xen/events.c | 44 |
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 | ||
1028 | static DEFINE_PER_CPU(unsigned, xed_nesting_count); | 1028 | static DEFINE_PER_CPU(unsigned, xed_nesting_count); |
1029 | static DEFINE_PER_CPU(unsigned int, last_word_idx) = { BITS_PER_LONG - 1 }; | 1029 | static DEFINE_PER_CPU(unsigned int, current_word_idx); |
1030 | static DEFINE_PER_CPU(unsigned int, last_bit_idx) = { BITS_PER_LONG - 1 }; | 1030 | static 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()); |