diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-08-20 23:46:25 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:52:59 -0400 |
commit | e89eb43863c2d9f11a3bbe766766fe646e6c50d9 (patch) | |
tree | 3d45bdf7efb5a37edb99f62cbea1d500b3003468 /arch/x86/kernel/io_apic.c | |
parent | 7ddfb650c7ef7a33a5ef11c0fdf5b3d837a47dba (diff) |
x86: sparse_irq needs spin_lock in allocations
Suresh Siddha noticed that we should have a spinlock around it.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/io_apic.c')
-rw-r--r-- | arch/x86/kernel/io_apic.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 34c74cf5c244..7ca556690474 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c | |||
@@ -146,6 +146,12 @@ static void init_one_irq_cfg(struct irq_cfg *cfg) | |||
146 | } | 146 | } |
147 | 147 | ||
148 | static struct irq_cfg *irq_cfgx; | 148 | static struct irq_cfg *irq_cfgx; |
149 | |||
150 | /* | ||
151 | * Protect the irq_cfgx_free freelist: | ||
152 | */ | ||
153 | static DEFINE_SPINLOCK(irq_cfg_lock); | ||
154 | |||
149 | #ifdef CONFIG_HAVE_SPARSE_IRQ | 155 | #ifdef CONFIG_HAVE_SPARSE_IRQ |
150 | static struct irq_cfg *irq_cfgx_free; | 156 | static struct irq_cfg *irq_cfgx_free; |
151 | #endif | 157 | #endif |
@@ -213,8 +219,9 @@ static struct irq_cfg *irq_cfg(unsigned int irq) | |||
213 | static struct irq_cfg *irq_cfg_alloc(unsigned int irq) | 219 | static struct irq_cfg *irq_cfg_alloc(unsigned int irq) |
214 | { | 220 | { |
215 | struct irq_cfg *cfg, *cfg_pri; | 221 | struct irq_cfg *cfg, *cfg_pri; |
216 | int i; | 222 | unsigned long flags; |
217 | int count = 0; | 223 | int count = 0; |
224 | int i; | ||
218 | 225 | ||
219 | cfg_pri = cfg = irq_cfgx; | 226 | cfg_pri = cfg = irq_cfgx; |
220 | while (cfg) { | 227 | while (cfg) { |
@@ -226,6 +233,7 @@ static struct irq_cfg *irq_cfg_alloc(unsigned int irq) | |||
226 | count++; | 233 | count++; |
227 | } | 234 | } |
228 | 235 | ||
236 | spin_lock_irqsave(&irq_cfg_lock, flags); | ||
229 | if (!irq_cfgx_free) { | 237 | if (!irq_cfgx_free) { |
230 | unsigned long phys; | 238 | unsigned long phys; |
231 | unsigned long total_bytes; | 239 | unsigned long total_bytes; |
@@ -263,6 +271,9 @@ static struct irq_cfg *irq_cfg_alloc(unsigned int irq) | |||
263 | else | 271 | else |
264 | irq_cfgx = cfg; | 272 | irq_cfgx = cfg; |
265 | cfg->irq = irq; | 273 | cfg->irq = irq; |
274 | |||
275 | spin_unlock_irqrestore(&irq_cfg_lock, flags); | ||
276 | |||
266 | printk(KERN_DEBUG "found new irq_cfg for irq %d\n", cfg->irq); | 277 | printk(KERN_DEBUG "found new irq_cfg for irq %d\n", cfg->irq); |
267 | #ifdef CONFIG_HAVE_SPARSE_IRQ_DEBUG | 278 | #ifdef CONFIG_HAVE_SPARSE_IRQ_DEBUG |
268 | { | 279 | { |