WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

Re: [XenPPC] [PATCH] Enable SMP and IPIs


On Oct 24, 2006, at 12:22 AM, Amos Waterland wrote:

This patch enables SMP and IPIs.  It works reliably on JS20 and JS21
blades.  It is not quite ready for submission, but I would greatly
appreciate any comments.

Note that the flurry of IPIs generated by domain creation seems to be a
waste of time.  Xen on x86 doesn't actually to do anything in response
to them, so I have made Xen on PPC properly deliver the event check but
then do nothing as well.  Comments?

The important thing this patch is missing is the ability to invoke
functions on a remote CPU, and I have left it out because I am not yet
happy with the convention, which is to grab a lock, put the target
address in a single global shared variable, invoke a memory barrier, and
send the IPI.  I am hoping to avoid a lock around that operation by
making a per-IPI-destination-CPU structure with lock, address, and ack
fields.  Comments?

It seems Linux-PPC does a similar thing, I'd be happy with borrowing that code:
  arch/powerpc/kernel/smp.c <global> 214 int smp_call_function ()

I will always encourage, "coming up with something better" but lets nail it first.

[snip]

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      Mon Oct 23 15:32:55 2006 -0400
@@ -358,6 +358,43 @@ static struct hw_interrupt_type *share_m

 #endif

+static inline struct mpic * mpic_from_ipi(unsigned int ipi)
+{
+       return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi);
+}
+
+static unsigned int mpic_startup_ipi(unsigned int irq)
+{
+    printk("%s\n", __func__);
+    struct mpic *pic = mpic_from_ipi(irq);
+    pic->hc_ipi.enable(irq);
+    return 0;
+}

at least in our code now, mpic pointer is static to this whole file so mpic_from_ipi() is unnecessary. We don't have any multi-mpic machines yet and looking at upstream Linux, they have solved this problem another way.

+
+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;
+
+ printk("%s: %d: %p: %s: %p\n", __func__, irq, handler, devname, dev_id);
+
+    action = xmalloc_bytes(sizeof(struct irqaction));

plan xmalloc() takes a type and does the sizeof() for you, so:
  action = xmalloc(struct irqaction);


+    if (!action)
+       BUG();

I know this is RFC, and you know I'm a bug fan of BUG(), but eventually I'd expect:
  BUG_ON(!action)
  if (!action)
        return -ENOMEM

+
+ action->handler = (void (*)(int, void *, struct cpu_user_regs *))handler;
can you cast this with a local variable and comment that Xen's irq action is older than Linux's.

+    action->name = devname;
+    action->dev_id = dev_id;
+
+    retval = setup_irq(irq, action);
+    if (retval)
+       BUG();

As the BUG above:
  BUG_ON(retval);
  if (reval)
    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;
 }

[snip]
diff -r 3dfeb3e4a03f xen/arch/powerpc/smp.c
--- a/xen/arch/powerpc/smp.c    Fri Oct 13 11:00:32 2006 -0400
+++ b/xen/arch/powerpc/smp.c    Mon Oct 23 23:15:45 2006 -0400
@@ -22,6 +22,8 @@
 #include <xen/smp.h>
 #include <asm/flushtlb.h>
 #include <asm/debugger.h>
+#include <asm/mpic.h>
+#include <asm/mach-default/irq_vectors.h>

 int smp_num_siblings = 1;
 int smp_num_cpus = 1;
@@ -46,11 +48,30 @@ void __flush_tlb_mask(cpumask_t mask, un
         unimplemented();
 }

+static void send_IPI_mask(cpumask_t mask, int vector)
+{
+    unsigned long cpus;
+
+    switch(vector) {
+    case CALL_FUNCTION_VECTOR:
+    case EVENT_CHECK_VECTOR:
+    case INVALIDATE_TLB_VECTOR:

I'm pretty sure we should not be supporting the INVALIDATE_TLB_VECTOR vector and will probably just do a broadcast TLB instead, do I'd like to see this BUG().

+       break;
+    default:
+       BUG();
+    }
+
+    BUG_ON(sizeof(mask.bits) != sizeof(unsigned long));
+    cpus = mask.bits[0];
+
+    mpic_send_ipi(vector, cpus);

I'd like to keep all knowledge of mpic in external.c and mpic_init.c, so let make a new function smp_send_ipi() in external.c and move the bounds checking there, sinec mpic_send_ipi() takes an unsigned int for cpus, you should make sure that the bounds check on that rather than unsigned long.

+}
+
 void smp_send_event_check_mask(cpumask_t mask)
 {
     cpu_clear(smp_processor_id(), mask);
     if (!cpus_empty(mask))
-        unimplemented();
+        send_IPI_mask(mask, EVENT_CHECK_VECTOR);
 }


@@ -78,3 +99,39 @@ int on_selected_cpus(
     unimplemented();
     return 0;
 }
+
+void smp_call_function_interrupt(struct cpu_user_regs *regs)
+{
+    BUG();
arch/powerpc/kernel/smp.c smp_call_function_interrupt 285 void smp_call_function_interrupt(void )
+    return;
+}
+
+void smp_event_check_interrupt(void)
+{
+    /* Like x86 we don't actually do anything with this IPI.  */
+    return;
+}
+
+void smp_invalidate_interrupt(void)
+{
+    BUG();
+    return;
+}
+
+void smp_message_recv(int msg, struct cpu_user_regs *regs)
+{
+    switch(msg) {
+    case CALL_FUNCTION_VECTOR:
+       smp_call_function_interrupt(regs);
+       break;
+    case EVENT_CHECK_VECTOR:
+        smp_event_check_interrupt();
+       break;
+    case INVALIDATE_TLB_VECTOR:
+        smp_invalidate_interrupt();
+       break;
+    default:
+       BUG();
+       break;
+    }
+}
diff -r 3dfeb3e4a03f xen/include/asm-powerpc/mach-default/ irq_vectors.h --- a/xen/include/asm-powerpc/mach-default/irq_vectors.h Fri Oct 13 11:00:32 2006 -0400 +++ b/xen/include/asm-powerpc/mach-default/irq_vectors.h Mon Oct 23 21:00:34 2006 -0400
@@ -37,8 +37,6 @@
 #define FAST_TRAP -1 /* 0x80 */
 #define FIRST_SYSTEM_VECTOR    -1

-#if 0
-

Please drop the entire contents of #if 0 here and only add the 3 you need below.

 /*
  * Vectors 0-16 in some cases are used for ISA interrupts.
  */
@@ -54,9 +52,12 @@
  */
 #define SPURIOUS_APIC_VECTOR   0xff
 #define ERROR_APIC_VECTOR      0xfe
-#define INVALIDATE_TLB_VECTOR  0xfd
-#define EVENT_CHECK_VECTOR     0xfc
-#define CALL_FUNCTION_VECTOR   0xfb
+
+#define CALL_FUNCTION_VECTOR   0x0
+#define EVENT_CHECK_VECTOR     0x1
+#define INVALIDATE_TLB_VECTOR  0x3
Drop the INVALIDATE_TLB_VECTOR

+
+#if 0

 #define THERMAL_APIC_VECTOR    0xf0
 /*


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

<Prev in Thread] Current Thread [Next in Thread>