* [PATCH 1/2] powerpc/ps3: Fix lost SMP IPIs
@ 2011-11-08 22:37 Geoff Levand
2011-11-09 9:53 ` Peter Zijlstra
0 siblings, 1 reply; 2+ messages in thread
From: Geoff Levand @ 2011-11-08 22:37 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: cbe-oss-dev, linuxppc-dev, Andre Heider, Peter Zijlstra
Fixes the PS3 bootup hang introduced in 3.0-rc1 by:
commit 317f394160e9beb97d19a84c39b7e5eb3d7815a
sched: Move the second half of ttwu() to the remote cpu
Move the PS3's LV1 EOI call lv1_end_of_interrupt_ext() from ps3_chip_eoi()
to ps3_get_irq() for IPI messages.
If lv1_send_event_locally() is called between a previous call to
lv1_send_event_locally() and the coresponding call to
lv1_end_of_interrupt_ext() the second event will not be delivered to the
target cpu.
The PS3's SMP IPIs are implemented using lv1_send_event_locally(), so if two
IPI messages of the same type are sent to the same target in a relatively
short period of time the second IPI event can become lost when
lv1_end_of_interrupt_ext() is called from ps3_chip_eoi().
CC: stable@kernel.org
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
arch/powerpc/platforms/ps3/interrupt.c | 23 ++++++++++++++++++++++-
arch/powerpc/platforms/ps3/platform.h | 1 +
arch/powerpc/platforms/ps3/smp.c | 2 ++
3 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 404bc52..1d6f4f4 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -88,6 +88,7 @@ struct ps3_private {
struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
u64 ppe_id;
u64 thread_id;
+ unsigned long ipi_mask;
};
static DEFINE_PER_CPU(struct ps3_private, ps3_private);
@@ -144,7 +145,11 @@ static void ps3_chip_unmask(struct irq_data *d)
static void ps3_chip_eoi(struct irq_data *d)
{
const struct ps3_private *pd = irq_data_get_irq_chip_data(d);
- lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
+
+ /* non-IPIs are EOIed here. */
+
+ if (!test_bit(63 - d->irq, &pd->ipi_mask))
+ lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
}
/**
@@ -691,6 +696,16 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
cpu, virq, pd->bmp.ipi_debug_brk_mask);
}
+void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq)
+{
+ struct ps3_private *pd = &per_cpu(ps3_private, cpu);
+
+ set_bit(63 - virq, &pd->ipi_mask);
+
+ DBG("%s:%d: cpu %u, virq %u, ipi_mask %lxh\n", __func__, __LINE__,
+ cpu, virq, pd->ipi_mask);
+}
+
static unsigned int ps3_get_irq(void)
{
struct ps3_private *pd = &__get_cpu_var(ps3_private);
@@ -720,6 +735,12 @@ static unsigned int ps3_get_irq(void)
BUG();
}
#endif
+
+ /* IPIs are EOIed here. */
+
+ if (test_bit(63 - plug, &pd->ipi_mask))
+ lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, plug);
+
return plug;
}
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 9a196a8..1a633ed 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -43,6 +43,7 @@ void ps3_mm_shutdown(void);
void ps3_init_IRQ(void);
void ps3_shutdown_IRQ(int cpu);
void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq);
+void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq);
/* smp */
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 4c44794..f609345 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -94,6 +94,8 @@ static void __init ps3_smp_setup_cpu(int cpu)
if (result)
virqs[i] = NO_IRQ;
+ else
+ ps3_register_ipi_irq(cpu, virqs[i]);
}
ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 1/2] powerpc/ps3: Fix lost SMP IPIs
2011-11-08 22:37 [PATCH 1/2] powerpc/ps3: Fix lost SMP IPIs Geoff Levand
@ 2011-11-09 9:53 ` Peter Zijlstra
0 siblings, 0 replies; 2+ messages in thread
From: Peter Zijlstra @ 2011-11-09 9:53 UTC (permalink / raw)
To: Geoff Levand; +Cc: cbe-oss-dev, Andre Heider, linuxppc-dev
On Tue, 2011-11-08 at 14:37 -0800, Geoff Levand wrote:
> Fixes the PS3 bootup hang introduced in 3.0-rc1 by:
>=20
> commit 317f394160e9beb97d19a84c39b7e5eb3d7815a
> sched: Move the second half of ttwu() to the remote cpu
>=20
> Move the PS3's LV1 EOI call lv1_end_of_interrupt_ext() from ps3_chip_eoi(=
)
> to ps3_get_irq() for IPI messages.
>=20
> If lv1_send_event_locally() is called between a previous call to
> lv1_send_event_locally() and the coresponding call to
> lv1_end_of_interrupt_ext() the second event will not be delivered to the
> target cpu.
>=20
> The PS3's SMP IPIs are implemented using lv1_send_event_locally(), so if =
two
> IPI messages of the same type are sent to the same target in a relatively
> short period of time the second IPI event can become lost when
> lv1_end_of_interrupt_ext() is called from ps3_chip_eoi().=20
Ah glad you found it! I'm not going to ack it since PPC guts are way
beyond me.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-11-09 9:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-08 22:37 [PATCH 1/2] powerpc/ps3: Fix lost SMP IPIs Geoff Levand
2011-11-09 9:53 ` Peter Zijlstra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).