mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-01 12:04:08 +00:00
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>
This commit is contained in:
parent
9a8ecae87a
commit
10b888d6ce
2 changed files with 9 additions and 3 deletions
|
@ -2528,14 +2528,15 @@ static void irq_complete_move(struct irq_desc **descp)
|
||||||
|
|
||||||
vector = ~get_irq_regs()->orig_ax;
|
vector = ~get_irq_regs()->orig_ax;
|
||||||
me = smp_processor_id();
|
me = smp_processor_id();
|
||||||
|
|
||||||
|
if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) {
|
||||||
#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
|
#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
|
||||||
*descp = desc = move_irq_desc(desc, me);
|
*descp = desc = move_irq_desc(desc, me);
|
||||||
/* get the new one */
|
/* get the new one */
|
||||||
cfg = desc->chip_data;
|
cfg = desc->chip_data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
|
|
||||||
send_cleanup_vector(cfg);
|
send_cleanup_vector(cfg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void irq_complete_move(struct irq_desc **descp) {}
|
static inline void irq_complete_move(struct irq_desc **descp) {}
|
||||||
|
|
|
@ -71,7 +71,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
|
||||||
desc = irq_desc_ptrs[irq];
|
desc = irq_desc_ptrs[irq];
|
||||||
|
|
||||||
if (desc && old_desc != desc)
|
if (desc && old_desc != desc)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
node = cpu_to_node(cpu);
|
node = cpu_to_node(cpu);
|
||||||
desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
|
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,
|
||||||
init_copy_one_irq_desc(irq, old_desc, desc, cpu);
|
init_copy_one_irq_desc(irq, old_desc, desc, cpu);
|
||||||
|
|
||||||
irq_desc_ptrs[irq] = desc;
|
irq_desc_ptrs[irq] = desc;
|
||||||
|
spin_unlock_irqrestore(&sparse_irq_lock, flags);
|
||||||
|
|
||||||
/* free the old one */
|
/* free the old one */
|
||||||
free_one_irq_desc(old_desc, desc);
|
free_one_irq_desc(old_desc, desc);
|
||||||
|
spin_unlock(&old_desc->lock);
|
||||||
kfree(old_desc);
|
kfree(old_desc);
|
||||||
|
spin_lock(&desc->lock);
|
||||||
|
|
||||||
|
return desc;
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
spin_unlock_irqrestore(&sparse_irq_lock, flags);
|
spin_unlock_irqrestore(&sparse_irq_lock, flags);
|
||||||
|
|
Loading…
Add table
Reference in a new issue