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 /kernel | |
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 'kernel')
-rw-r--r-- | kernel/irq/handle.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 24c83a3cee4d..d638a911cbc1 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -107,6 +107,11 @@ static void init_kstat_irqs(struct irq_desc *desc, int nr_desc, int nr) | |||
107 | } | 107 | } |
108 | } | 108 | } |
109 | 109 | ||
110 | /* | ||
111 | * Protect the sparse_irqs_free freelist: | ||
112 | */ | ||
113 | static DEFINE_SPINLOCK(sparse_irq_lock); | ||
114 | |||
110 | #ifdef CONFIG_HAVE_SPARSE_IRQ | 115 | #ifdef CONFIG_HAVE_SPARSE_IRQ |
111 | static struct irq_desc *sparse_irqs_free; | 116 | static struct irq_desc *sparse_irqs_free; |
112 | struct irq_desc *sparse_irqs; | 117 | struct irq_desc *sparse_irqs; |
@@ -166,11 +171,13 @@ struct irq_desc *irq_to_desc(unsigned int irq) | |||
166 | } | 171 | } |
167 | return NULL; | 172 | return NULL; |
168 | } | 173 | } |
174 | |||
169 | struct irq_desc *irq_to_desc_alloc(unsigned int irq) | 175 | struct irq_desc *irq_to_desc_alloc(unsigned int irq) |
170 | { | 176 | { |
171 | struct irq_desc *desc, *desc_pri; | 177 | struct irq_desc *desc, *desc_pri; |
172 | int i; | 178 | unsigned long flags; |
173 | int count = 0; | 179 | int count = 0; |
180 | int i; | ||
174 | 181 | ||
175 | desc_pri = desc = sparse_irqs; | 182 | desc_pri = desc = sparse_irqs; |
176 | while (desc) { | 183 | while (desc) { |
@@ -182,6 +189,7 @@ struct irq_desc *irq_to_desc_alloc(unsigned int irq) | |||
182 | count++; | 189 | count++; |
183 | } | 190 | } |
184 | 191 | ||
192 | spin_lock_irqsave(&sparse_irq_lock, flags); | ||
185 | /* | 193 | /* |
186 | * we run out of pre-allocate ones, allocate more | 194 | * we run out of pre-allocate ones, allocate more |
187 | */ | 195 | */ |
@@ -223,6 +231,9 @@ struct irq_desc *irq_to_desc_alloc(unsigned int irq) | |||
223 | else | 231 | else |
224 | sparse_irqs = desc; | 232 | sparse_irqs = desc; |
225 | desc->irq = irq; | 233 | desc->irq = irq; |
234 | |||
235 | spin_unlock_irqrestore(&sparse_irq_lock, flags); | ||
236 | |||
226 | printk(KERN_DEBUG "found new irq_desc for irq %d\n", desc->irq); | 237 | printk(KERN_DEBUG "found new irq_desc for irq %d\n", desc->irq); |
227 | #ifdef CONFIG_HAVE_SPARSE_IRQ_DEBUG | 238 | #ifdef CONFIG_HAVE_SPARSE_IRQ_DEBUG |
228 | { | 239 | { |