Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (30 commits) x86, apic: Enable lapic nmi watchdog on AMD Family 11h x86: Remove unnecessary mdelay() from cpu_disable_common() x86, ioapic: Document another case when level irq is seen as an edge x86, ioapic: Fix the EOI register detection mechanism x86, io-apic: Move the effort of clearing remoteIRR explicitly before migrating the irq x86: SGI UV: Map low MMR ranges x86: apic: Print out SRAT table APIC id in hex x86: Re-get cfg_new in case reuse/move irq_desc x86: apic: Remove not needed #ifdef x86: io-apic: IO-APIC MMIO should not fail on resource insertion x86: Remove asm/apicnum.h x86: apic: Do not use stacked physid_mask_t x86, apic: Get rid of apicid_to_cpu_present assign on 64-bit x86, ioapic: Use snrpintf while set names for IO-APIC resourses x86, apic: Use PAGE_SIZE instead of numbers x86: Remove local_irq_enable()/local_irq_disable() in fixup_irqs() x86: Use EOI register in io-apic on intel platforms x86: Force irq complete move during cpu offline x86: Remove move_cleanup_count from irq_cfg x86, intr-remap: Avoid irq_chip mask/unmask in fixup_irqs() for intr-remapping ...
This commit is contained in:
commit
a77d2e081b
27 changed files with 808 additions and 417 deletions
|
@ -274,3 +274,93 @@ void smp_generic_interrupt(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
|
||||
void fixup_irqs(void)
|
||||
{
|
||||
unsigned int irq, vector;
|
||||
static int warned;
|
||||
struct irq_desc *desc;
|
||||
|
||||
for_each_irq_desc(irq, desc) {
|
||||
int break_affinity = 0;
|
||||
int set_affinity = 1;
|
||||
const struct cpumask *affinity;
|
||||
|
||||
if (!desc)
|
||||
continue;
|
||||
if (irq == 2)
|
||||
continue;
|
||||
|
||||
/* interrupt's are disabled at this point */
|
||||
spin_lock(&desc->lock);
|
||||
|
||||
affinity = desc->affinity;
|
||||
if (!irq_has_action(irq) ||
|
||||
cpumask_equal(affinity, cpu_online_mask)) {
|
||||
spin_unlock(&desc->lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Complete the irq move. This cpu is going down and for
|
||||
* non intr-remapping case, we can't wait till this interrupt
|
||||
* arrives at this cpu before completing the irq move.
|
||||
*/
|
||||
irq_force_complete_move(irq);
|
||||
|
||||
if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
|
||||
break_affinity = 1;
|
||||
affinity = cpu_all_mask;
|
||||
}
|
||||
|
||||
if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->mask)
|
||||
desc->chip->mask(irq);
|
||||
|
||||
if (desc->chip->set_affinity)
|
||||
desc->chip->set_affinity(irq, affinity);
|
||||
else if (!(warned++))
|
||||
set_affinity = 0;
|
||||
|
||||
if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->unmask)
|
||||
desc->chip->unmask(irq);
|
||||
|
||||
spin_unlock(&desc->lock);
|
||||
|
||||
if (break_affinity && set_affinity)
|
||||
printk("Broke affinity for irq %i\n", irq);
|
||||
else if (!set_affinity)
|
||||
printk("Cannot set affinity for irq %i\n", irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can remove mdelay() and then send spuriuous interrupts to
|
||||
* new cpu targets for all the irqs that were handled previously by
|
||||
* this cpu. While it works, I have seen spurious interrupt messages
|
||||
* (nothing wrong but still...).
|
||||
*
|
||||
* So for now, retain mdelay(1) and check the IRR and then send those
|
||||
* interrupts to new targets as this cpu is already offlined...
|
||||
*/
|
||||
mdelay(1);
|
||||
|
||||
for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
|
||||
unsigned int irr;
|
||||
|
||||
if (__get_cpu_var(vector_irq)[vector] < 0)
|
||||
continue;
|
||||
|
||||
irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
|
||||
if (irr & (1 << (vector % 32))) {
|
||||
irq = __get_cpu_var(vector_irq)[vector];
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
spin_lock(&desc->lock);
|
||||
if (desc->chip->retrigger)
|
||||
desc->chip->retrigger(irq);
|
||||
spin_unlock(&desc->lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue