diff options
author | Yinghai Lu <yinghai@kernel.org> | 2009-01-31 17:50:07 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-01 05:36:31 -0500 |
commit | 10b888d6cec2688e65e9e128b14bf98ecd199da2 (patch) | |
tree | b29736b4fabe128b8a3db00b22c71e98424d03d4 /kernel/irq/numa_migrate.c | |
parent | 9a8ecae87a2b698964b1db9ea504ba1099f479fc (diff) |
irq, x86: fix lock status with numa_migrate_irq_desc
Eric Paris reported:
> I have an hp dl785g5 which is unable to successfully run
> 2.6.29-0.66.rc3.fc11.x86_64 or 2.6.29-rc2-next-20090126. During bootup
> (early in userspace daemons starting) I get the below BUG, which quickly
> renders the machine dead. I assume it is because sparse_irq_lock never
> gets released when the BUG kills that task.
Adjust lock sequence when migrating a descriptor with
CONFIG_NUMA_MIGRATE_IRQ_DESC enabled.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/irq/numa_migrate.c')
-rw-r--r-- | kernel/irq/numa_migrate.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c index ecf765c6a77a..acd88356ac76 100644 --- a/kernel/irq/numa_migrate.c +++ b/kernel/irq/numa_migrate.c | |||
@@ -71,7 +71,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, | |||
71 | desc = irq_desc_ptrs[irq]; | 71 | desc = irq_desc_ptrs[irq]; |
72 | 72 | ||
73 | if (desc && old_desc != desc) | 73 | if (desc && old_desc != desc) |
74 | goto out_unlock; | 74 | goto out_unlock; |
75 | 75 | ||
76 | node = cpu_to_node(cpu); | 76 | node = cpu_to_node(cpu); |
77 | desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); | 77 | desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); |
@@ -84,10 +84,15 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, | |||
84 | init_copy_one_irq_desc(irq, old_desc, desc, cpu); | 84 | init_copy_one_irq_desc(irq, old_desc, desc, cpu); |
85 | 85 | ||
86 | irq_desc_ptrs[irq] = desc; | 86 | irq_desc_ptrs[irq] = desc; |
87 | spin_unlock_irqrestore(&sparse_irq_lock, flags); | ||
87 | 88 | ||
88 | /* free the old one */ | 89 | /* free the old one */ |
89 | free_one_irq_desc(old_desc, desc); | 90 | free_one_irq_desc(old_desc, desc); |
91 | spin_unlock(&old_desc->lock); | ||
90 | kfree(old_desc); | 92 | kfree(old_desc); |
93 | spin_lock(&desc->lock); | ||
94 | |||
95 | return desc; | ||
91 | 96 | ||
92 | out_unlock: | 97 | out_unlock: |
93 | spin_unlock_irqrestore(&sparse_irq_lock, flags); | 98 | spin_unlock_irqrestore(&sparse_irq_lock, flags); |