#define PIRQ_NEEDS_EOI (1 << 0)
#define PIRQ_SHAREABLE (1 << 1)
-- static struct irq_info *irq_info;
-- static int *pirq_to_irq;
--
static int *evtchn_to_irq;
-- struct cpu_evtchn_s {
-- unsigned long bits[NR_EVENT_CHANNELS/BITS_PER_LONG];
-- };
-- static __initdata struct cpu_evtchn_s init_evtchn_mask = {
-- .bits[0 ... (NR_EVENT_CHANNELS/BITS_PER_LONG)-1] = ~0ul,
-- };
- static struct cpu_evtchn_s __refdata *cpu_evtchn_mask_p = &init_evtchn_mask;
- static struct cpu_evtchn_s *cpu_evtchn_mask_p = &init_evtchn_mask;
--
-- static inline unsigned long *cpu_evtchn_mask(int cpu)
-- {
-- return cpu_evtchn_mask_p[cpu].bits;
-- }
++ static DEFINE_PER_CPU(unsigned long [NR_EVENT_CHANNELS/BITS_PER_LONG],
++ cpu_evtchn_mask);
/* Xen will never allocate port zero for any purpose. */
#define VALID_EVTCHN(chn) ((chn) != 0)
set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
handle_level_irq, name);
-- irq_info[irq] = mk_pirq_info(0, pirq, 0, vector);
-- pirq_to_irq[pirq] = irq;
- ret = set_irq_msi(irq, msidesc);
++ xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, 0);
- ret = set_irq_msi(irq, msidesc);
++ ret = irq_set_msi_desc(irq, msidesc);
if (ret < 0)
goto error_irq;
out:
wmb();
#endif
pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
- - while (pending_words != 0) {
+ +
+ + start_word_idx = __this_cpu_read(current_word_idx);
+ + start_bit_idx = __this_cpu_read(current_bit_idx);
+ +
+ + word_idx = start_word_idx;
+ +
+ + for (i = 0; pending_words != 0; i++) {
unsigned long pending_bits;
- - int word_idx = __ffs(pending_words);
- - pending_words &= ~(1UL << word_idx);
+ + unsigned long words;
+
- while ((pending_bits = active_evtchns(cpu, s, word_idx)) != 0) {
- int bit_idx = __ffs(pending_bits);
- int port = (word_idx * BITS_PER_LONG) + bit_idx;
- int irq = evtchn_to_irq[port];
+ + words = MASK_LSBS(pending_words, word_idx);
+ +
+ + /*
+ + * If we masked out all events, wrap to beginning.
+ + */
+ + if (words == 0) {
+ + word_idx = 0;
+ + bit_idx = 0;
+ + continue;
+ + }
+ + word_idx = __ffs(words);
+ +
+ + pending_bits = active_evtchns(cpu, s, word_idx);
+ + bit_idx = 0; /* usually scan entire word from start */
+ + if (word_idx == start_word_idx) {
+ + /* We scan the starting word in two parts */
+ + if (i == 0)
+ + /* 1st time: start in the middle */
+ + bit_idx = start_bit_idx;
+ + else
+ + /* 2nd time: mask bits done already */
+ + bit_idx &= (1UL << start_bit_idx) - 1;
+ + }
+
- while ((pending_bits = active_evtchns(cpu, s, word_idx)) != 0) {
- int bit_idx = __ffs(pending_bits);
- int port = (word_idx * BITS_PER_LONG) + bit_idx;
- int irq = evtchn_to_irq[port];
+ + do {
+ + unsigned long bits;
+ + int port, irq;
struct irq_desc *desc;
+ + bits = MASK_LSBS(pending_bits, bit_idx);
+ +
+ + /* If we masked out all events, move on. */
+ + if (bits == 0)
+ + break;
+ +
+ + bit_idx = __ffs(bits);
+ +
+ + /* Process port. */
+ + port = (word_idx * BITS_PER_LONG) + bit_idx;
+ + irq = evtchn_to_irq[port];
+ +
mask_evtchn(port);
clear_evtchn(port);