Re: [XenPPC] [PATCH] SMP and IPI support

2006-10-27 Thread Amos Waterland
On Thu, Oct 26, 2006 at 11:24:32PM -0400, Amos Waterland wrote:
> Enable SMP and IPI support, including remote function invocation.

It took over 1000 attempts but I did see a case of the timebase sync
hang.  I will try to track this down.

 changeset   : 25c51961bd3f
 machines: kpblade1 cso91 cso103
 pass: 1103
 fail: 1
 transient   : 1
 total   : 1105
 reliability : 99%

 25c51961bd3f/cso103/xen.log.2006-10-27.000551
 =
 (XEN) Min 6 (score -281), Max 7 (score 235)
 (XEN) Final offset: 7 (93/300)
 (XEN) Synchronizing timebase


___
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel


[XenPPC] [PATCH] SMP and IPI support

2006-10-26 Thread Amos Waterland
Enable SMP and IPI support, including remote function invocation.

There are a number of subtle issues fixed in this patch.  I believe it
is a candidate for merging.

I have tested this extensively on JS21 and model 884221X JS20 blades,
and to a degree on Maple.  I would appreciate further testing on Maple
and model 884241X JS20 blades.

Signed-off-by: Amos Waterland <[EMAIL PROTECTED]>

---

 changeset   : 25c51961bd3f
 machines: kpblade1 cso91 cso103
 pass: 162
 fail: 0
 transient   : 1
 total   : 163
 reliability : 100%

---

 arch/powerpc/external.c|   32 +
 arch/powerpc/mpic.c|9 -
 arch/powerpc/mpic_init.c   |   48 
 arch/powerpc/setup.c   |   49 +
 arch/powerpc/smp.c |  135 +++--
 include/asm-powerpc/mach-default/irq_vectors.h |   22 
 include/asm-powerpc/smp.h  |   17 +++
 7 files changed, 256 insertions(+), 56 deletions(-)

diff -r 3dfeb3e4a03f xen/arch/powerpc/external.c
--- a/xen/arch/powerpc/external.c   Fri Oct 13 11:00:32 2006 -0400
+++ b/xen/arch/powerpc/external.c   Thu Oct 26 16:49:44 2006 -0400
@@ -82,7 +82,16 @@ void do_external(struct cpu_user_regs *r
 
 vec = xen_mpic_get_irq(regs);
 
-if (vec != -1) {
+if (vector_is_ipi(vec)) {
+   /* do_IRQ is fundamentally broken for reliable IPI delivery.  */
+   irq_desc_t *desc = &irq_desc[vec];
+   regs->entry_vector = vec;
+   spin_lock(&desc->lock);
+   desc->handler->ack(vec);
+   desc->action->handler(vector_to_irq(vec), desc->action->dev_id, regs);
+   desc->handler->end(vec);
+   spin_unlock(&desc->lock);
+} else if (vec != -1) {
 DBG("EE:0x%lx isrc: %d\n", regs->msr, vec);
 regs->entry_vector = vec;
 do_IRQ(regs);
@@ -253,3 +262,24 @@ int ioapic_guest_write(unsigned long phy
 BUG_ON(val != val);
 return 0;
 }
+
+void send_IPI_mask(cpumask_t mask, int vector)
+{
+unsigned int cpus;
+int const bits = 8 * sizeof(cpus);
+
+switch(vector) {
+case CALL_FUNCTION_VECTOR:
+case EVENT_CHECK_VECTOR:
+   break;
+default:
+   BUG();
+   return;
+}
+
+BUG_ON(NR_CPUS > bits);
+BUG_ON(fls(mask.bits[0]) > bits);
+
+cpus = mask.bits[0];
+mpic_send_ipi(vector, cpus);
+}
diff -r 3dfeb3e4a03f xen/arch/powerpc/mpic.c
--- a/xen/arch/powerpc/mpic.c   Fri Oct 13 11:00:32 2006 -0400
+++ b/xen/arch/powerpc/mpic.c   Mon Oct 23 22:57:51 2006 -0400
@@ -27,10 +27,6 @@
 
 
 #define alloc_bootmem(x) xmalloc_bytes(x)
-#define request_irq(irq, handler, f, devname, dev_id) \
-panic("IPI requested: %d: %p: %s: %p\n", irq, handler, devname, dev_id)
-
-typedef int irqreturn_t;
 
 #define IRQ_NONE   (0)
 #define IRQ_HANDLED(1)
@@ -96,11 +92,6 @@ typedef int irqreturn_t;
 #endif
 #include 
 #include 
-
-static inline void smp_message_recv(int msg, struct pt_regs *regs)
-{
-return;
-}
 
 #ifdef DEBUG
 #define DBG(fmt...) printk(fmt)
diff -r 3dfeb3e4a03f xen/arch/powerpc/mpic_init.c
--- a/xen/arch/powerpc/mpic_init.c  Fri Oct 13 11:00:32 2006 -0400
+++ b/xen/arch/powerpc/mpic_init.c  Thu Oct 26 16:48:19 2006 -0400
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mpic_init.h"
 #include "oftree.h"
 #include "of-devtree.h"
@@ -358,6 +359,42 @@ static struct hw_interrupt_type *share_m
 
 #endif
 
+static unsigned int mpic_startup_ipi(unsigned int irq)
+{
+mpic->hc_ipi.enable(irq);
+return 0;
+}
+
+int request_irq(unsigned int irq,
+   irqreturn_t (*handler)(int, void *, struct cpu_user_regs *),
+   unsigned long irqflags, const char * devname, void *dev_id)
+{
+int retval;
+struct irqaction *action;
+void (*func)(int, void *, struct cpu_user_regs *);
+
+action = xmalloc(struct irqaction);
+if (!action) {
+   BUG();
+   return -ENOMEM;
+}
+
+/* Xen's handler prototype is slightly different than Linux's.  */
+func = (void (*)(int, void *, struct cpu_user_regs *))handler;
+
+action->handler = func;
+action->name = devname;
+action->dev_id = dev_id;
+
+retval = setup_irq(irq, action);
+if (retval) {
+   BUG();
+   xfree(action);
+}
+
+return retval;
+}
+
 struct hw_interrupt_type *xen_mpic_init(struct hw_interrupt_type *xen_irq)
 {
 unsigned int isu_size;
@@ -397,6 +434,11 @@ struct hw_interrupt_type *xen_mpic_init(
 hit = share_mpic(&mpic->hc_irq, xen_irq);
 
 printk("%s: success\n", __func__);
+
+mpic->hc_ipi.ack = xen_irq->ack;
+mpic->hc_ipi.startup = mpic_startup_ipi;
+mpic_request_ipis();
+
 return hit;
 }
 
@@ -406,3 +448,9 @@ int xen_mpic_get_irq(struct cpu_user_reg
 
return mpic_get_one_irq(mpic, regs);
 }
+
+int vector_is_ipi(int vector)
+{
+BUG_ON(!mpic);
+return (mpic->ipi_offset <= vector) && (vector < mpic->ipi_offset + 4);
+}