From: Linus Torvalds Date: Fri, 18 Mar 2011 01:27:49 +0000 (-0700) Subject: Merge branches 'stable/irq.fairness' and 'stable/irq.ween_of_nr_irqs' of git://git... X-Git-Tag: v2.6.39-rc1~438 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=commitdiff_plain;h=5a39837f76b7ded29afdf6ed2c2d5e56107179b7 Merge branches 'stable/irq.fairness' and 'stable/irq.ween_of_nr_irqs' of git://git./linux/kernel/git/konrad/xen * 'stable/irq.fairness' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen: events: Remove redundant clear of l2i at end of round-robin loop xen: events: Make round-robin scan fairer by snapshotting each l2 word once only xen: events: Clean up round-robin evtchn scan. xen: events: Make last processed event channel a per-cpu variable. xen: events: Process event channels notifications in round-robin order. * 'stable/irq.ween_of_nr_irqs' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen: events: Fix compile error if CONFIG_SMP is not defined. xen: events: correct locking in xen_irq_from_pirq xen: events: propagate irq allocation failure instead of panicking xen: events: do not workaround too-small nr_irqs xen: events: remove use of nr_irqs as upper bound on number of pirqs xen: events: dynamically allocate irq info structures xen: events: maintain a list of Xen interrupts xen: events: push setup of irq<->{evtchn,ipi,virq,pirq} maps into irq_info init functions xen: events: turn irq_info constructors into initialiser functions xen: events: use per-cpu variable for cpu_evtchn_mask xen: events: refactor GSI pirq bindings functions xen: events: rename restore_cpu_pirqs -> restore_pirqs xen: events: remove unused public functions xen: events: fix xen_map_pirq_gsi error return xen: events: simplify comment xen: events: separate two unrelated halves of if condition Fix up trivial conflicts in drivers/xen/events.c --- 5a39837f76b7ded29afdf6ed2c2d5e56107179b7 diff --cc drivers/xen/events.c index 65f5068afd84,8786e06c4180,4591853f6ebc..02b5a9c05cfa --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@@@ -103,23 -103,23 -107,10 +107,10 @@@@ struct irq_inf #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) @@@@ -672,9 -672,9 -693,8 +693,8 @@@@ int xen_bind_pirq_msi_to_irq(struct pci 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: @@@@ -1094,17 -1066,57 -1082,17 +1130,57 @@@@ static void __xen_evtchn_do_upcall(void 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);