Commit b794ef26 authored by Jiang Liu's avatar Jiang Liu Committed by Thomas Gleixner

x86, irq: Protect __clear_irq_vector() with vector_lock

Function __clear_irq_vector() accesses vector related data structure,
so protect it with vector_lock. Also rename it as clear_irq_vector().
Signed-off-by: default avatarJiang Liu <jiang.liu@linux.intel.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Prarit Bhargava <prarit@redhat.com>
Link: http://lkml.kernel.org/r/1414397531-28254-8-git-send-email-jiang.liu@linux.intel.comSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent cb39288c
...@@ -1349,10 +1349,12 @@ int assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) ...@@ -1349,10 +1349,12 @@ int assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
return err; return err;
} }
static void __clear_irq_vector(int irq, struct irq_cfg *cfg) static void clear_irq_vector(int irq, struct irq_cfg *cfg)
{ {
int cpu, vector; int cpu, vector;
unsigned long flags;
raw_spin_lock_irqsave(&vector_lock, flags);
BUG_ON(!cfg->vector); BUG_ON(!cfg->vector);
vector = cfg->vector; vector = cfg->vector;
...@@ -1362,8 +1364,11 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) ...@@ -1362,8 +1364,11 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
cfg->vector = 0; cfg->vector = 0;
cpumask_clear(cfg->domain); cpumask_clear(cfg->domain);
if (likely(!cfg->move_in_progress)) if (likely(!cfg->move_in_progress)) {
raw_spin_unlock_irqrestore(&vector_lock, flags);
return; return;
}
for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) {
for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
if (per_cpu(vector_irq, cpu)[vector] != irq) if (per_cpu(vector_irq, cpu)[vector] != irq)
...@@ -1373,6 +1378,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) ...@@ -1373,6 +1378,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
} }
} }
cfg->move_in_progress = 0; cfg->move_in_progress = 0;
raw_spin_unlock_irqrestore(&vector_lock, flags);
} }
void __setup_vector_irq(int cpu) void __setup_vector_irq(int cpu)
...@@ -1499,7 +1505,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, ...@@ -1499,7 +1505,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
&dest)) { &dest)) {
pr_warn("Failed to obtain apicid for ioapic %d, pin %d\n", pr_warn("Failed to obtain apicid for ioapic %d, pin %d\n",
mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); mpc_ioapic_id(attr->ioapic), attr->ioapic_pin);
__clear_irq_vector(irq, cfg); clear_irq_vector(irq, cfg);
return; return;
} }
...@@ -1513,7 +1519,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, ...@@ -1513,7 +1519,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
if (x86_io_apic_ops.setup_entry(irq, &entry, dest, cfg->vector, attr)) { if (x86_io_apic_ops.setup_entry(irq, &entry, dest, cfg->vector, attr)) {
pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n",
mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); mpc_ioapic_id(attr->ioapic), attr->ioapic_pin);
__clear_irq_vector(irq, cfg); clear_irq_vector(irq, cfg);
return; return;
} }
...@@ -3083,12 +3089,9 @@ int arch_setup_hwirq(unsigned int irq, int node) ...@@ -3083,12 +3089,9 @@ int arch_setup_hwirq(unsigned int irq, int node)
void arch_teardown_hwirq(unsigned int irq) void arch_teardown_hwirq(unsigned int irq)
{ {
struct irq_cfg *cfg = irq_cfg(irq); struct irq_cfg *cfg = irq_cfg(irq);
unsigned long flags;
free_remapped_irq(irq); free_remapped_irq(irq);
raw_spin_lock_irqsave(&vector_lock, flags); clear_irq_vector(irq, cfg);
__clear_irq_vector(irq, cfg);
raw_spin_unlock_irqrestore(&vector_lock, flags);
free_irq_cfg(irq, cfg); free_irq_cfg(irq, cfg);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment