aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/io_apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/io_apic.c')
-rw-r--r--arch/x86/kernel/io_apic.c65
1 files changed, 37 insertions, 28 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index 7a3f2028e2eb..679e7bbbbcd6 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -1140,6 +1140,20 @@ static void __clear_irq_vector(int irq)
1140 1140
1141 cfg->vector = 0; 1141 cfg->vector = 0;
1142 cpus_clear(cfg->domain); 1142 cpus_clear(cfg->domain);
1143
1144 if (likely(!cfg->move_in_progress))
1145 return;
1146 cpus_and(mask, cfg->old_domain, cpu_online_map);
1147 for_each_cpu_mask_nr(cpu, mask) {
1148 for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
1149 vector++) {
1150 if (per_cpu(vector_irq, cpu)[vector] != irq)
1151 continue;
1152 per_cpu(vector_irq, cpu)[vector] = -1;
1153 break;
1154 }
1155 }
1156 cfg->move_in_progress = 0;
1143} 1157}
1144 1158
1145void __setup_vector_irq(int cpu) 1159void __setup_vector_irq(int cpu)
@@ -2202,10 +2216,9 @@ static void set_ir_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
2202asmlinkage void smp_irq_move_cleanup_interrupt(void) 2216asmlinkage void smp_irq_move_cleanup_interrupt(void)
2203{ 2217{
2204 unsigned vector, me; 2218 unsigned vector, me;
2219
2205 ack_APIC_irq(); 2220 ack_APIC_irq();
2206#ifdef CONFIG_X86_64
2207 exit_idle(); 2221 exit_idle();
2208#endif
2209 irq_enter(); 2222 irq_enter();
2210 2223
2211 me = smp_processor_id(); 2224 me = smp_processor_id();
@@ -3594,27 +3607,7 @@ int __init io_apic_get_redir_entries (int ioapic)
3594 3607
3595int __init probe_nr_irqs(void) 3608int __init probe_nr_irqs(void)
3596{ 3609{
3597 int idx; 3610 return NR_IRQS;
3598 int nr = 0;
3599#ifndef CONFIG_XEN
3600 int nr_min = 32;
3601#else
3602 int nr_min = NR_IRQS;
3603#endif
3604
3605 for (idx = 0; idx < nr_ioapics; idx++)
3606 nr += io_apic_get_redir_entries(idx) + 1;
3607
3608 /* double it for hotplug and msi and nmi */
3609 nr <<= 1;
3610
3611 /* something wrong ? */
3612 if (nr < nr_min)
3613 nr = nr_min;
3614 if (WARN_ON(nr > NR_IRQS))
3615 nr = NR_IRQS;
3616
3617 return nr;
3618} 3611}
3619 3612
3620/* -------------------------------------------------------------------------- 3613/* --------------------------------------------------------------------------
@@ -3761,7 +3754,9 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
3761void __init setup_ioapic_dest(void) 3754void __init setup_ioapic_dest(void)
3762{ 3755{
3763 int pin, ioapic, irq, irq_entry; 3756 int pin, ioapic, irq, irq_entry;
3757 struct irq_desc *desc;
3764 struct irq_cfg *cfg; 3758 struct irq_cfg *cfg;
3759 cpumask_t mask;
3765 3760
3766 if (skip_ioapic_setup == 1) 3761 if (skip_ioapic_setup == 1)
3767 return; 3762 return;
@@ -3778,16 +3773,30 @@ void __init setup_ioapic_dest(void)
3778 * cpu is online. 3773 * cpu is online.
3779 */ 3774 */
3780 cfg = irq_cfg(irq); 3775 cfg = irq_cfg(irq);
3781 if (!cfg->vector) 3776 if (!cfg->vector) {
3782 setup_IO_APIC_irq(ioapic, pin, irq, 3777 setup_IO_APIC_irq(ioapic, pin, irq,
3783 irq_trigger(irq_entry), 3778 irq_trigger(irq_entry),
3784 irq_polarity(irq_entry)); 3779 irq_polarity(irq_entry));
3780 continue;
3781
3782 }
3783
3784 /*
3785 * Honour affinities which have been set in early boot
3786 */
3787 desc = irq_to_desc(irq);
3788 if (desc->status &
3789 (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
3790 mask = desc->affinity;
3791 else
3792 mask = TARGET_CPUS;
3793
3785#ifdef CONFIG_INTR_REMAP 3794#ifdef CONFIG_INTR_REMAP
3786 else if (intr_remapping_enabled) 3795 if (intr_remapping_enabled)
3787 set_ir_ioapic_affinity_irq(irq, TARGET_CPUS); 3796 set_ir_ioapic_affinity_irq(irq, mask);
3788#endif
3789 else 3797 else
3790 set_ioapic_affinity_irq(irq, TARGET_CPUS); 3798#endif
3799 set_ioapic_affinity_irq(irq, mask);
3791 } 3800 }
3792 3801
3793 } 3802 }