aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r--arch/x86/kernel/apic/io_apic.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 4d871339ba4f..ab8ca9327c06 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1349,10 +1349,12 @@ int assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
1349 return err; 1349 return err;
1350} 1350}
1351 1351
1352static void __clear_irq_vector(int irq, struct irq_cfg *cfg) 1352static void clear_irq_vector(int irq, struct irq_cfg *cfg)
1353{ 1353{
1354 int cpu, vector; 1354 int cpu, vector;
1355 unsigned long flags;
1355 1356
1357 raw_spin_lock_irqsave(&vector_lock, flags);
1356 BUG_ON(!cfg->vector); 1358 BUG_ON(!cfg->vector);
1357 1359
1358 vector = cfg->vector; 1360 vector = cfg->vector;
@@ -1362,8 +1364,11 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
1362 cfg->vector = 0; 1364 cfg->vector = 0;
1363 cpumask_clear(cfg->domain); 1365 cpumask_clear(cfg->domain);
1364 1366
1365 if (likely(!cfg->move_in_progress)) 1367 if (likely(!cfg->move_in_progress)) {
1368 raw_spin_unlock_irqrestore(&vector_lock, flags);
1366 return; 1369 return;
1370 }
1371
1367 for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { 1372 for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) {
1368 for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { 1373 for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
1369 if (per_cpu(vector_irq, cpu)[vector] != irq) 1374 if (per_cpu(vector_irq, cpu)[vector] != irq)
@@ -1373,6 +1378,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
1373 } 1378 }
1374 } 1379 }
1375 cfg->move_in_progress = 0; 1380 cfg->move_in_progress = 0;
1381 raw_spin_unlock_irqrestore(&vector_lock, flags);
1376} 1382}
1377 1383
1378void __setup_vector_irq(int cpu) 1384void __setup_vector_irq(int cpu)
@@ -1499,7 +1505,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
1499 &dest)) { 1505 &dest)) {
1500 pr_warn("Failed to obtain apicid for ioapic %d, pin %d\n", 1506 pr_warn("Failed to obtain apicid for ioapic %d, pin %d\n",
1501 mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); 1507 mpc_ioapic_id(attr->ioapic), attr->ioapic_pin);
1502 __clear_irq_vector(irq, cfg); 1508 clear_irq_vector(irq, cfg);
1503 1509
1504 return; 1510 return;
1505 } 1511 }
@@ -1513,7 +1519,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
1513 if (x86_io_apic_ops.setup_entry(irq, &entry, dest, cfg->vector, attr)) { 1519 if (x86_io_apic_ops.setup_entry(irq, &entry, dest, cfg->vector, attr)) {
1514 pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", 1520 pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n",
1515 mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); 1521 mpc_ioapic_id(attr->ioapic), attr->ioapic_pin);
1516 __clear_irq_vector(irq, cfg); 1522 clear_irq_vector(irq, cfg);
1517 1523
1518 return; 1524 return;
1519 } 1525 }
@@ -3083,12 +3089,9 @@ int arch_setup_hwirq(unsigned int irq, int node)
3083void arch_teardown_hwirq(unsigned int irq) 3089void arch_teardown_hwirq(unsigned int irq)
3084{ 3090{
3085 struct irq_cfg *cfg = irq_cfg(irq); 3091 struct irq_cfg *cfg = irq_cfg(irq);
3086 unsigned long flags;
3087 3092
3088 free_remapped_irq(irq); 3093 free_remapped_irq(irq);
3089 raw_spin_lock_irqsave(&vector_lock, flags); 3094 clear_irq_vector(irq, cfg);
3090 __clear_irq_vector(irq, cfg);
3091 raw_spin_unlock_irqrestore(&vector_lock, flags);
3092 free_irq_cfg(irq, cfg); 3095 free_irq_cfg(irq, cfg);
3093} 3096}
3094 3097