[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Clean up Xen's event-channel interface, and semantics for binding



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 1d375ce8e0e04871782b94408e8b8fe3d399cdd6
# Parent  579d1e771025f8eb36ae537650499dd9a6b66e7b

Clean up Xen's event-channel interface, and semantics for binding
to VCPUs.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 579d1e771025 -r 1d375ce8e0e0 
linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h
--- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h 
Fri Jul  8 12:24:58 2005
+++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h 
Fri Jul  8 14:17:54 2005
@@ -126,8 +126,8 @@
 /* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */
 extern int  bind_virq_to_irq(int virq);
 extern void unbind_virq_from_irq(int virq);
-extern int  bind_ipi_on_cpu_to_irq(int cpu, int ipi);
-extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi);
+extern int  bind_ipi_to_irq(int ipi);
+extern void unbind_ipi_from_irq(int ipi);
 extern int  bind_evtchn_to_irq(int evtchn);
 extern void unbind_evtchn_from_irq(int evtchn);
 
diff -r 579d1e771025 -r 1d375ce8e0e0 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Fri Jul  8 12:24:58 2005
+++ b/xen/common/event_channel.c        Fri Jul  8 14:17:54 2005
@@ -220,12 +220,10 @@
 
     chn1->u.interdomain.remote_dom  = d2;
     chn1->u.interdomain.remote_port = (u16)port2;
-    chn1->notify_vcpu_id            = 0;
     chn1->state                     = ECS_INTERDOMAIN;
     
     chn2->u.interdomain.remote_dom  = d1;
     chn2->u.interdomain.remote_port = (u16)port1;
-    chn2->notify_vcpu_id            = 0;
     chn2->state                     = ECS_INTERDOMAIN;
 
  out:
@@ -285,10 +283,7 @@
 {
     struct evtchn *chn;
     struct domain *d = current->domain;
-    int            port, ipi_vcpu = bind->ipi_vcpu;
-
-    if ( (ipi_vcpu >= MAX_VIRT_CPUS) || (d->vcpu[ipi_vcpu] == NULL) )
-        return -EINVAL;
+    int            port;
 
     spin_lock(&d->evtchn_lock);
 
@@ -296,7 +291,7 @@
     {
         chn = evtchn_from_port(d, port);
         chn->state          = ECS_IPI;
-        chn->notify_vcpu_id = ipi_vcpu;
+        chn->notify_vcpu_id = current->vcpu_id;
     }
 
     spin_unlock(&d->evtchn_lock);
@@ -325,8 +320,6 @@
         goto out;
 
     chn = evtchn_from_port(d, port);
-
-    chn->notify_vcpu_id = 0;
 
     d->pirq_to_evtchn[pirq] = port;
     rc = pirq_guest_bind(d->vcpu[0], pirq, 
@@ -441,7 +434,9 @@
         BUG();
     }
 
-    chn1->state = ECS_FREE;
+    /* Reset binding to vcpu0 when the channel is freed. */
+    chn1->state          = ECS_FREE;
+    chn1->notify_vcpu_id = 0;
 
  out:
     if ( d2 != NULL )
@@ -570,12 +565,13 @@
         status->u.virq = chn->u.virq;
         break;
     case ECS_IPI:
-        status->status     = EVTCHNSTAT_ipi;
-        status->u.ipi_vcpu = chn->notify_vcpu_id;
+        status->status = EVTCHNSTAT_ipi;
         break;
     default:
         BUG();
     }
+
+    status->vcpu = chn->notify_vcpu_id;
 
  out:
     spin_unlock(&d->evtchn_lock);
@@ -583,13 +579,16 @@
     return rc;
 }
 
-static long evtchn_rebind(evtchn_rebind_t *bind) 
+static long evtchn_bind_vcpu(evtchn_bind_vcpu_t *bind) 
 {
     struct domain *d    = current->domain;
     int            port = bind->port;
     int            vcpu = bind->vcpu;
     struct evtchn *chn;
-    long             rc = 0;
+    long           rc = 0;
+
+    if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] == NULL) )
+        return -EINVAL;
 
     spin_lock(&d->evtchn_lock);
 
@@ -600,7 +599,17 @@
     }
 
     chn = evtchn_from_port(d, port);
-    chn->notify_vcpu_id = vcpu;
+    switch ( chn->state )
+    {
+    case ECS_UNBOUND:
+    case ECS_INTERDOMAIN:
+    case ECS_PIRQ:
+        chn->notify_vcpu_id = vcpu;
+        break;
+    default:
+        rc = -EINVAL;
+        break;
+    }
 
  out:
     spin_unlock(&d->evtchn_lock);
@@ -664,10 +673,8 @@
             rc = -EFAULT;
         break;
 
-    case EVTCHNOP_rebind:
-        rc = evtchn_rebind(&op.u.rebind);
-        if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
-            rc = -EFAULT;
+    case EVTCHNOP_bind_vcpu:
+        rc = evtchn_bind_vcpu(&op.u.bind_vcpu);
         break;
 
     default:
diff -r 579d1e771025 -r 1d375ce8e0e0 
linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c  Fri Jul  8 12:24:58 2005
+++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c  Fri Jul  8 14:17:54 2005
@@ -236,17 +236,17 @@
     spin_unlock(&irq_mapping_update_lock);
 }
 
-int bind_ipi_on_cpu_to_irq(int cpu, int ipi)
+int bind_ipi_on_cpu_to_irq(int ipi)
 {
     evtchn_op_t op;
     int evtchn, irq;
+    int cpu = smp_processor_id();
 
     spin_lock(&irq_mapping_update_lock);
 
     if ( (evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == 0 )
     {
-        op.cmd                 = EVTCHNOP_bind_ipi;
-        op.u.bind_ipi.ipi_vcpu = cpu;
+        op.cmd = EVTCHNOP_bind_ipi;
         if ( HYPERVISOR_event_channel_op(&op) != 0 )
             panic("Failed to bind virtual IPI %d on cpu %d\n", ipi, cpu);
         evtchn = op.u.bind_ipi.port;
@@ -278,9 +278,9 @@
 
     spin_lock(&irq_mapping_update_lock);
 
-    op.cmd          = EVTCHNOP_rebind;
-    op.u.rebind.port = evtchn;
-    op.u.rebind.vcpu = newcpu;
+    op.cmd              = EVTCHNOP_bind_vcpu;
+    op.u.bind_vcpu.port = evtchn;
+    op.u.bind_vcpu.vcpu = newcpu;
     if ( HYPERVISOR_event_channel_op(&op) != 0 )
        printk(KERN_INFO "Failed to rebind IPI%d to CPU%d\n",ipi,newcpu);
 
@@ -294,18 +294,19 @@
 
     spin_lock(&irq_mapping_update_lock);
 
-    op.cmd          = EVTCHNOP_rebind;
-    op.u.rebind.port = evtchn;
-    op.u.rebind.vcpu = newcpu;
+    op.cmd              = EVTCHNOP_bind_vcpu;
+    op.u.bind_vcpu.port = evtchn;
+    op.u.bind_vcpu.vcpu = newcpu;
     if ( HYPERVISOR_event_channel_op(&op) != 0 )
        printk(KERN_INFO "Failed to rebind IRQ%d to CPU%d\n",irq,newcpu);
 
     spin_unlock(&irq_mapping_update_lock);
 }
 
-void unbind_ipi_on_cpu_from_irq(int cpu, int ipi)
-{
-    evtchn_op_t op;
+void unbind_ipi_from_irq(int ipi)
+{
+    evtchn_op_t op;
+    int cpu    = smp_processor_id();
     int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
     int irq    = irq_to_evtchn[evtchn];
 
diff -r 579d1e771025 -r 1d375ce8e0e0 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Fri Jul  8 12:24:58 2005
+++ b/xen/include/public/dom0_ops.h     Fri Jul  8 14:17:54 2005
@@ -19,7 +19,7 @@
  * This makes sure that old versions of dom0 tools will stop working in a
  * well-defined way (rather than crashing the machine, for instance).
  */
-#define DOM0_INTERFACE_VERSION   0xAAAA100D
+#define DOM0_INTERFACE_VERSION   0xAAAA100E
 
 /************************************************************************/
 
diff -r 579d1e771025 -r 1d375ce8e0e0 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h        Fri Jul  8 12:24:58 2005
+++ b/xen/include/public/event_channel.h        Fri Jul  8 14:17:54 2005
@@ -89,8 +89,6 @@
  */
 #define EVTCHNOP_bind_ipi         7
 typedef struct evtchn_bind_ipi {
-    /* IN parameters. */
-    u32 ipi_vcpu;
     /* OUT parameters. */
     u32 port;
 } evtchn_bind_ipi_t;
@@ -144,6 +142,7 @@
 #define EVTCHNSTAT_virq         4  /* Channel is bound to a virtual IRQ line */
 #define EVTCHNSTAT_ipi          5  /* Channel is bound to a virtual IPI line */
     u32     status;
+    u32     vcpu;                  /* VCPU to which this channel is bound.   */
     union {
         struct {
             domid_t dom;
@@ -154,16 +153,25 @@
         } interdomain; /* EVTCHNSTAT_interdomain */
         u32 pirq;      /* EVTCHNSTAT_pirq        */
         u32 virq;      /* EVTCHNSTAT_virq        */
-        u32 ipi_vcpu;  /* EVTCHNSTAT_ipi         */
     } u;
 } evtchn_status_t;
 
-#define EVTCHNOP_rebind        8
-typedef struct {
+/*
+ * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an
+ * event is pending.
+ * NOTES:
+ *  1. IPI- and VIRQ-bound channels always notify the vcpu that initialised
+ *     the binding. This binding cannot be changed.
+ *  2. All other channels notify vcpu0 by default. This default is set when
+ *     the channel is allocated (a port that is freed and subsequently reused
+ *     has its binding reset to vcpu0).
+ */
+#define EVTCHNOP_bind_vcpu        8
+typedef struct evtchn_bind_vcpu {
     /* IN parameters. */
-    u32 port;                         /*  0 */
-    u32 vcpu;                         /*  4 */
-} evtchn_rebind_t; /* 8 bytes */
+    u32 port;
+    u32 vcpu;
+} evtchn_bind_vcpu_t;
 
 typedef struct evtchn_op {
     u32 cmd; /* EVTCHNOP_* */
@@ -176,7 +184,7 @@
         evtchn_close_t            close;
         evtchn_send_t             send;
         evtchn_status_t           status;
-        evtchn_rebind_t           rebind;
+        evtchn_bind_vcpu_t        bind_vcpu;
     } u;
 } evtchn_op_t;
 
diff -r 579d1e771025 -r 1d375ce8e0e0 
linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
--- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h   
Fri Jul  8 12:24:58 2005
+++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h   
Fri Jul  8 14:17:54 2005
@@ -128,8 +128,8 @@
 /* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */
 extern int  bind_virq_to_irq(int virq);
 extern void unbind_virq_from_irq(int virq);
-extern int  bind_ipi_on_cpu_to_irq(int cpu, int ipi);
-extern void unbind_ipi_on_cpu_from_irq(int cpu, int ipi);
+extern int  bind_ipi_to_irq(int ipi);
+extern void unbind_ipi_from_irq(int ipi);
 extern int  bind_evtchn_to_irq(int evtchn);
 extern void unbind_evtchn_from_irq(int evtchn);
 
diff -r 579d1e771025 -r 1d375ce8e0e0 
linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    Fri Jul  8 
12:24:58 2005
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    Fri Jul  8 
14:17:54 2005
@@ -1533,13 +1533,13 @@
        int cpu = smp_processor_id();
 
        per_cpu(resched_irq, cpu) =
-               bind_ipi_on_cpu_to_irq(cpu, RESCHEDULE_VECTOR);
+               bind_ipi_to_irq(RESCHEDULE_VECTOR);
        sprintf(resched_name[cpu], "resched%d", cpu);
        BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt,
                           SA_INTERRUPT, resched_name[cpu], NULL));
 
        per_cpu(callfunc_irq, cpu) =
-               bind_ipi_on_cpu_to_irq(cpu, CALL_FUNCTION_VECTOR);
+               bind_ipi_to_irq(CALL_FUNCTION_VECTOR);
        sprintf(callfunc_name[cpu], "callfunc%d", cpu);
        BUG_ON(request_irq(per_cpu(callfunc_irq, cpu),
                           smp_call_function_interrupt,

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.