tree eafa49d8a9e6f4d725a498626029b7abf3ff9d91
parent 5f5024130287a9467a41b9f94ec170958ae45cbd
author Arnd Bergmann <[EMAIL PROTECTED]> Thu, 18 Aug 2005 19:35:21 +0200
committer Paul Mackerras <[EMAIL PROTECTED]> Fri, 09 Sep 2005 22:11:34 +1000

[PATCH] ppc64: fix IPI on bpa_iic

This fixes a severe bug in the bpa_iic driver that caused
all sorts of problems.

We had been using incorrect priority values for inter processor
interrupts, which resulted in always doing CALL_FUNCTION
instead of RESCHEDULE or DEBUGGER_BREAK.

The symptoms cured by this patch include bad performance on
SMP systems spurious kernel panics in the IPI code.

Signed-off-by: Arnd Bergmann <[EMAIL PROTECTED]>
Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>

 arch/ppc64/kernel/bpa_iic.c |   28 +++++++++++++++++++++-------
 1 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c
--- a/arch/ppc64/kernel/bpa_iic.c
+++ b/arch/ppc64/kernel/bpa_iic.c
@@ -205,6 +205,18 @@ static struct iic_regs __iomem *find_iic
 }
 
 #ifdef CONFIG_SMP
+
+/* Use the highest interrupt priorities for IPI */
+static inline int iic_ipi_to_irq(int ipi)
+{
+       return IIC_IPI_OFFSET + IIC_NUM_IPIS - 1 - ipi;
+}
+
+static inline int iic_irq_to_ipi(int irq)
+{
+       return IIC_NUM_IPIS - 1 - (irq - IIC_IPI_OFFSET);
+}
+
 void iic_setup_cpu(void)
 {
        out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
@@ -212,18 +224,20 @@ void iic_setup_cpu(void)
 
 void iic_cause_IPI(int cpu, int mesg)
 {
-       out_be64(&per_cpu(iic, cpu).regs->generate, mesg);
+       out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) 
<< 4);
 }
 
 static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
 {
-
-       smp_message_recv(irq - IIC_IPI_OFFSET, regs);
+       smp_message_recv(iic_irq_to_ipi(irq), regs);
        return IRQ_HANDLED;
 }
 
-static void iic_request_ipi(int irq, const char *name)
+static void iic_request_ipi(int ipi, const char *name)
 {
+       int irq;
+
+       irq = iic_ipi_to_irq(ipi);
        /* IPIs are marked SA_INTERRUPT as they must run with irqs
         * disabled */
        get_irq_desc(irq)->handler = &iic_pic;
@@ -233,10 +247,10 @@ static void iic_request_ipi(int irq, con
 
 void iic_request_IPIs(void)
 {
-       iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call");
-       iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched");
+       iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call");
+       iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched");
 #ifdef CONFIG_DEBUGGER
-       iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
+       iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
 #endif /* CONFIG_DEBUGGER */
 }
 #endif /* CONFIG_SMP */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to