Commit 98febb25 authored by Anton Blanchard's avatar Anton Blanchard Committed by Linus Torvalds

[PATCH] ppc64: fix hotplug irq migration code

In migrate_irqs_away we werent converting a virtual irq to a real one.  We
ended up passing the wrong irq numbers to the hypervisor and migration of
affinitised irqs on cpu hot unplug didnt work.

Also clarify the rtas_stop_self printk.
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 039f45db
...@@ -500,7 +500,7 @@ void rtas_stop_self(void) ...@@ -500,7 +500,7 @@ void rtas_stop_self(void)
BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE); BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE);
printk("%u %u Ready to die...\n", printk("cpu %u (hwid %u) Ready to die...\n",
smp_processor_id(), hard_smp_processor_id()); smp_processor_id(), hard_smp_processor_id());
enter_rtas(__pa(rtas_args)); enter_rtas(__pa(rtas_args));
......
...@@ -657,9 +657,7 @@ void xics_migrate_irqs_away(void) ...@@ -657,9 +657,7 @@ void xics_migrate_irqs_away(void)
int set_indicator = rtas_token("set-indicator"); int set_indicator = rtas_token("set-indicator");
const unsigned int giqs = 9005UL; /* Global Interrupt Queue Server */ const unsigned int giqs = 9005UL; /* Global Interrupt Queue Server */
int status = 0; int status = 0;
unsigned int irq, cpu = smp_processor_id(); unsigned int irq, virq, cpu = smp_processor_id();
int xics_status[2];
unsigned long flags;
BUG_ON(set_indicator == RTAS_UNKNOWN_SERVICE); BUG_ON(set_indicator == RTAS_UNKNOWN_SERVICE);
...@@ -676,12 +674,20 @@ void xics_migrate_irqs_away(void) ...@@ -676,12 +674,20 @@ void xics_migrate_irqs_away(void)
ops->cppr_info(cpu, DEFAULT_PRIORITY); ops->cppr_info(cpu, DEFAULT_PRIORITY);
iosync(); iosync();
printk(KERN_WARNING "HOTPLUG: Migrating IRQs away\n"); for_each_irq(virq) {
for_each_irq(irq) { irq_desc_t *desc;
irq_desc_t *desc = get_irq_desc(irq); int xics_status[2];
unsigned long flags;
/* We cant set affinity on ISA interrupts */
if (virq < irq_offset_value())
continue;
desc = get_irq_desc(virq);
irq = virt_irq_to_real(irq_offset_down(virq));
/* We need to get IPIs still. */ /* We need to get IPIs still. */
if (irq_offset_down(irq) == XICS_IPI) if (irq == XICS_IPI || irq == NO_IRQ)
continue; continue;
/* We only need to migrate enabled IRQS */ /* We only need to migrate enabled IRQS */
...@@ -696,7 +702,7 @@ void xics_migrate_irqs_away(void) ...@@ -696,7 +702,7 @@ void xics_migrate_irqs_away(void)
if (status) { if (status) {
printk(KERN_ERR "migrate_irqs_away: irq=%d " printk(KERN_ERR "migrate_irqs_away: irq=%d "
"ibm,get-xive returns %d\n", "ibm,get-xive returns %d\n",
irq, status); virq, status);
goto unlock; goto unlock;
} }
...@@ -709,21 +715,20 @@ void xics_migrate_irqs_away(void) ...@@ -709,21 +715,20 @@ void xics_migrate_irqs_away(void)
goto unlock; goto unlock;
printk(KERN_WARNING "IRQ %d affinity broken off cpu %u\n", printk(KERN_WARNING "IRQ %d affinity broken off cpu %u\n",
irq, cpu); virq, cpu);
/* Reset affinity to all cpus */ /* Reset affinity to all cpus */
xics_status[0] = default_distrib_server; xics_status[0] = default_distrib_server;
status = rtas_call(ibm_set_xive, 3, 1, NULL, status = rtas_call(ibm_set_xive, 3, 1, NULL, irq,
irq, xics_status[0], xics_status[1]); xics_status[0], xics_status[1]);
if (status) if (status)
printk(KERN_ERR "migrate_irqs_away irq=%d " printk(KERN_ERR "migrate_irqs_away irq=%d "
"ibm,set-xive returns %d\n", "ibm,set-xive returns %d\n",
irq, status); virq, status);
unlock: unlock:
spin_unlock_irqrestore(&desc->lock, flags); spin_unlock_irqrestore(&desc->lock, flags);
} }
} }
#endif #endif
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