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-changelog

[Xen-changelog] Change how event channels are allocated and used by the

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Change how event channels are allocated and used by the control
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 06 Oct 2005 15:16:11 +0000
Delivery-date: Thu, 06 Oct 2005 15:13:41 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 4083eb31def03aa7cb98edf4a390e2f94459efe2
# Parent  cd228621e1fd4bc0f404b80e6c618ae02d0c1173
Change how event channels are allocated and used by the control
tools. /dev/xen/evtchn is now used by daemons to connect to
remote domains: the advantage is that the local ports are garbage
collected automatically if the daemon dies. xen no longer
constructs end-to-end event-channel port pairs -- it allocates an
unbound port in new domU and writes that port to xenstore. It is
then picked up by teh appropriate daemon which does interdomain bind
via /dev/xen/evtchn.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r cd228621e1fd -r 4083eb31def0 
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Thu Oct  6 14:12:31 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Thu Oct  6 15:07:52 2005
@@ -44,9 +44,9 @@
 #include <linux/poll.h>
 #include <linux/irq.h>
 #include <linux/init.h>
-#define XEN_EVTCHN_MASK_OPS
+#include <linux/gfp.h>
 #include <asm-xen/evtchn.h>
-#include <linux/gfp.h>
+#include <asm-xen/linux-public/evtchn.h>
 
 struct per_user_data {
        /* Notification ring, accessed via /dev/xen/evtchn. */
@@ -78,7 +78,8 @@
                        u->ring[EVTCHN_RING_MASK(u->ring_prod)] = (u16)port;
                        if (u->ring_cons == u->ring_prod++) {
                                wake_up_interruptible(&u->evtchn_wait);
-                               kill_fasync(&u->evtchn_async_queue, SIGIO, 
POLL_IN);
+                               kill_fasync(&u->evtchn_async_queue,
+                                           SIGIO, POLL_IN);
                        }
                } else {
                        u->ring_overflow = 1;
@@ -208,38 +209,100 @@
 static int evtchn_ioctl(struct inode *inode, struct file *file,
                         unsigned int cmd, unsigned long arg)
 {
-       int rc = 0;
+       int rc;
        struct per_user_data *u = file->private_data;
+       evtchn_op_t op = { 0 };
 
        spin_lock_irq(&port_user_lock);
     
        switch (cmd) {
-       case EVTCHN_RESET:
+       case IOCTL_EVTCHN_BIND_VIRQ: {
+               struct ioctl_evtchn_bind_virq bind;
+
+               rc = -EFAULT;
+               if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
+                       break;
+
+               op.cmd              = EVTCHNOP_bind_virq;
+               op.u.bind_virq.virq = bind.virq;
+               op.u.bind_virq.vcpu = 0;
+               rc = HYPERVISOR_event_channel_op(&op);
+               if (rc != 0)
+                       break;
+
+               rc = op.u.bind_virq.port;
+               port_user[rc] = u;
+               unmask_evtchn(rc);
+               break;
+       }
+
+       case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
+               struct ioctl_evtchn_bind_interdomain bind;
+
+               rc = -EFAULT;
+               if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
+                       break;
+
+               op.cmd                      = EVTCHNOP_bind_interdomain;
+               op.u.bind_interdomain.dom1  = DOMID_SELF;
+               op.u.bind_interdomain.dom2  = bind.remote_domain;
+               op.u.bind_interdomain.port1 = 0;
+               op.u.bind_interdomain.port2 = bind.remote_port;
+               rc = HYPERVISOR_event_channel_op(&op);
+               if (rc != 0)
+                       break;
+
+               rc = op.u.bind_interdomain.port1;
+               port_user[rc] = u;
+               unmask_evtchn(rc);
+               break;
+       }
+
+       case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
+               struct ioctl_evtchn_bind_unbound_port bind;
+
+               rc = -EFAULT;
+               if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
+                       break;
+
+               op.cmd                        = EVTCHNOP_alloc_unbound;
+               op.u.alloc_unbound.dom        = DOMID_SELF;
+               op.u.alloc_unbound.remote_dom = bind.remote_domain;
+               rc = HYPERVISOR_event_channel_op(&op);
+               if (rc != 0)
+                       break;
+
+               rc = op.u.alloc_unbound.port;
+               port_user[rc] = u;
+               unmask_evtchn(rc);
+               break;
+       }
+
+       case IOCTL_EVTCHN_UNBIND: {
+               struct ioctl_evtchn_unbind unbind;
+
+               rc = -EFAULT;
+               if (copy_from_user(&unbind, (void *)arg, sizeof(unbind)))
+                       break;
+
+               if (unbind.port >= NR_EVENT_CHANNELS) {
+                       rc = -EINVAL;
+               } else if (port_user[unbind.port] != u) {
+                       rc = -ENOTCONN;
+               } else {
+                       port_user[unbind.port] = NULL;
+                       mask_evtchn(unbind.port);
+                       rc = 0;
+               }
+               break;
+       }
+
+       case IOCTL_EVTCHN_RESET: {
                /* Initialise the ring to empty. Clear errors. */
                u->ring_cons = u->ring_prod = u->ring_overflow = 0;
-               break;
-
-       case EVTCHN_BIND:
-               if (arg >= NR_EVENT_CHANNELS) {
-                       rc = -EINVAL;
-               } else if (port_user[arg] != NULL) {
-                       rc = -EISCONN;
-               } else {
-                       port_user[arg] = u;
-                       unmask_evtchn(arg);
-               }
-               break;
-
-       case EVTCHN_UNBIND:
-               if (arg >= NR_EVENT_CHANNELS) {
-                       rc = -EINVAL;
-               } else if (port_user[arg] != u) {
-                       rc = -ENOTCONN;
-               } else {
-                       port_user[arg] = NULL;
-                       mask_evtchn(arg);
-               }
-               break;
+               rc = 0;
+               break;
+       }
 
        default:
                rc = -ENOSYS;
@@ -295,6 +358,7 @@
 {
        int i;
        struct per_user_data *u = filp->private_data;
+       evtchn_op_t op = { 0 };
 
        spin_lock_irq(&port_user_lock);
 
@@ -302,11 +366,16 @@
 
        for (i = 0; i < NR_EVENT_CHANNELS; i++)
        {
-               if (port_user[i] == u)
-               {
-                       port_user[i] = NULL;
-                       mask_evtchn(i);
-               }
+               if (port_user[i] != u)
+                       continue;
+
+               port_user[i] = NULL;
+               mask_evtchn(i);
+
+               op.cmd          = EVTCHNOP_close;
+               op.u.close.dom  = DOMID_SELF;
+               op.u.close.port = i;
+               BUG_ON(HYPERVISOR_event_channel_op(&op));
        }
 
        spin_unlock_irq(&port_user_lock);
diff -r cd228621e1fd -r 4083eb31def0 
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Thu Oct  6 14:12:31 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Thu Oct  6 15:07:52 2005
@@ -129,21 +129,6 @@
        (void)HYPERVISOR_event_channel_op(&op);
 }
 
-/*
- * CHARACTER-DEVICE DEFINITIONS
- */
-
-/* /dev/xen/evtchn resides at device number major=10, minor=201 */
-#define EVTCHN_MINOR 201
-
-/* /dev/xen/evtchn ioctls: */
-/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
-#define EVTCHN_RESET  _IO('E', 1)
-/* EVTCHN_BIND: Bind to teh specified event-channel port. */
-#define EVTCHN_BIND   _IO('E', 2)
-/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
-#define EVTCHN_UNBIND _IO('E', 3)
-
 #endif /* __ASM_EVTCHN_H__ */
 
 /*
diff -r cd228621e1fd -r 4083eb31def0 
linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h
--- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h       Thu Oct 
 6 14:12:31 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h       Thu Oct 
 6 15:07:52 2005
@@ -3,7 +3,7 @@
  * 
  * Interface to /proc/xen/privcmd.
  * 
- * Copyright (c) 2003-2004, K A Fraser
+ * Copyright (c) 2003-2005, K A Fraser
  * 
  * This file may be distributed separately from the Linux kernel, or
  * incorporated into other software packages, subject to the following license:
@@ -27,39 +27,39 @@
  * IN THE SOFTWARE.
  */
 
-#ifndef __PRIVCMD_H__
-#define __PRIVCMD_H__
+#ifndef __LINUX_PUBLIC_PRIVCMD_H__
+#define __LINUX_PUBLIC_PRIVCMD_H__
 
 typedef struct privcmd_hypercall
 {
-    unsigned long op;
-    unsigned long arg[5];
+       unsigned long op;
+       unsigned long arg[5];
 } privcmd_hypercall_t;
 
 typedef struct privcmd_mmap_entry {
-    unsigned long va;
-    unsigned long mfn;
-    unsigned long npages;
+       unsigned long va;
+       unsigned long mfn;
+       unsigned long npages;
 } privcmd_mmap_entry_t; 
 
 typedef struct privcmd_mmap {
-    int num;
-    domid_t dom; /* target domain */
-    privcmd_mmap_entry_t *entry;
+       int num;
+       domid_t dom; /* target domain */
+       privcmd_mmap_entry_t *entry;
 } privcmd_mmap_t; 
 
 typedef struct privcmd_mmapbatch {
-    int num;     /* number of pages to populate */
-    domid_t dom; /* target domain */
-    unsigned long addr;  /* virtual address */
-    unsigned long *arr; /* array of mfns - top nibble set on err */
+       int num;     /* number of pages to populate */
+       domid_t dom; /* target domain */
+       unsigned long addr;  /* virtual address */
+       unsigned long *arr; /* array of mfns - top nibble set on err */
 } privcmd_mmapbatch_t; 
 
 typedef struct privcmd_blkmsg
 {
-    unsigned long op;
-    void         *buf;
-    int           buf_size;
+       unsigned long op;
+       void         *buf;
+       int           buf_size;
 } privcmd_blkmsg_t;
 
 /*
@@ -67,16 +67,26 @@
  * @arg: &privcmd_hypercall_t
  * Return: Value returned from execution of the specified hypercall.
  */
-#define IOCTL_PRIVCMD_HYPERCALL         \
-    _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
+#define IOCTL_PRIVCMD_HYPERCALL                                        \
+       _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
 
-#define IOCTL_PRIVCMD_MMAP             \
-    _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
-#define IOCTL_PRIVCMD_MMAPBATCH             \
-    _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
-#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN \
-    _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
-#define IOCTL_PRIVCMD_INITDOMAIN_STORE \
-    _IOC(_IOC_READ, 'P', 5, 0)
+#define IOCTL_PRIVCMD_MMAP                                     \
+       _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
+#define IOCTL_PRIVCMD_MMAPBATCH                                        \
+       _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
+#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN                  \
+       _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
+#define IOCTL_PRIVCMD_INITDOMAIN_STORE                         \
+       _IOC(_IOC_READ, 'P', 5, 0)
 
-#endif /* __PRIVCMD_H__ */
+#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r cd228621e1fd -r 4083eb31def0 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Thu Oct  6 14:12:31 2005
+++ b/tools/console/daemon/io.c Thu Oct  6 15:07:52 2005
@@ -1,4 +1,4 @@
-/*\
+/*
  *  Copyright (C) International Business Machines  Corp., 2005
  *  Author(s): Anthony Liguori <aliguori@xxxxxxxxxx>
  *
@@ -16,14 +16,15 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-\*/
+ */
 
 #define _GNU_SOURCE
 
 #include "utils.h"
 #include "io.h"
-#include "xenctrl.h"
-#include "xs.h"
+#include <xenctrl.h>
+#include <xs.h>
+#include <xen/linux/evtchn.h>
 
 #include <malloc.h>
 #include <stdlib.h>
@@ -225,16 +226,14 @@
        return ret;
 }
 
-#define EVENTCHN_BIND          _IO('E', 2)
-#define EVENTCHN_UNBIND        _IO('E', 3)
-
 static int domain_create_ring(struct domain *dom)
 {
-       int err, local_port, ring_ref;
+       int err, remote_port, ring_ref, rc;
+       struct ioctl_evtchn_bind_interdomain bind;
 
        err = xs_gather(xs, dom->conspath,
                        "ring-ref", "%u", &ring_ref,
-                       "port", "%i", &local_port,
+                       "port", "%i", &remote_port,
                        NULL);
        if (err)
                goto out;
@@ -252,26 +251,28 @@
                dom->ring_ref = ring_ref;
        }
 
-       if (local_port != dom->local_port) {
-               dom->local_port = -1;
-               if (dom->evtchn_fd != -1)
-                       close(dom->evtchn_fd);
-               /* Opening evtchn independently for each console is a bit
-                * wastefule, but that's how the code is structured... */
-               dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
-               if (dom->evtchn_fd == -1) {
-                       err = errno;
-                       goto out;
-               }
+       dom->local_port = -1;
+       if (dom->evtchn_fd != -1)
+               close(dom->evtchn_fd);
+
+       /* Opening evtchn independently for each console is a bit
+        * wasteful, but that's how the code is structured... */
+       dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
+       if (dom->evtchn_fd == -1) {
+               err = errno;
+               goto out;
+       }
  
-               if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, local_port) == -1) {
-                       err = errno;
-                       close(dom->evtchn_fd);
-                       dom->evtchn_fd = -1;
-                       goto out;
-               }
-               dom->local_port = local_port;
-       }
+       bind.remote_domain = dom->domid;
+       bind.remote_port   = remote_port;
+       rc = ioctl(dom->evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+       if (rc == -1) {
+               err = errno;
+               close(dom->evtchn_fd);
+               dom->evtchn_fd = -1;
+               goto out;
+       }
+       dom->local_port = rc;
 
  out:
        return err;
diff -r cd228621e1fd -r 4083eb31def0 tools/debugger/pdb/pdb_xen.c
--- a/tools/debugger/pdb/pdb_xen.c      Thu Oct  6 14:12:31 2005
+++ b/tools/debugger/pdb/pdb_xen.c      Thu Oct  6 15:07:52 2005
@@ -43,11 +43,7 @@
 
 
 #include <sys/ioctl.h>
-
-/* /dev/xen/evtchn ioctls */
-#define EVTCHN_RESET  _IO('E', 1)                   /* clear & reinit buffer */
-#define EVTCHN_BIND   _IO('E', 2)                   /* bind to event channel */
-#define EVTCHN_UNBIND _IO('E', 3)               /* unbind from event channel */
+#include <xen/linux/evtchn.h>
 
 int
 xen_evtchn_bind (int evtchn_fd, int idx)
diff -r cd228621e1fd -r 4083eb31def0 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Thu Oct  6 14:12:31 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c      Thu Oct  6 15:07:52 2005
@@ -49,10 +49,13 @@
 
 #include <xenctrl.h>
 #include <xen/io/ioreq.h>
+#include <xen/linux/evtchn.h>
 
 #include "cpu.h"
 #include "exec-all.h"
 #include "vl.h"
+
+extern int domid;
 
 void *shared_vram;
 
@@ -119,7 +122,7 @@
 //the evtchn fd for polling
 int evtchn_fd = -1;
 //the evtchn port for polling the notification, should be inputed as bochs's 
parameter
-u16 ioreq_port = 0;
+u16 ioreq_remote_port, ioreq_local_port;
 
 //some functions to handle the io req packet
 void
@@ -156,9 +159,9 @@
        int rc;
        u16 buf[2];
        rc = read(evtchn_fd, buf, 2);
-       if (rc == 2 && buf[0] == ioreq_port){//got only one matched 16bit port 
index
+       if (rc == 2 && buf[0] == ioreq_local_port){//got only one matched 16bit 
port index
                // unmask the wanted port again
-               write(evtchn_fd, &ioreq_port, 2);
+               write(evtchn_fd, &ioreq_local_port, 2);
 
                //get the io packet from shared memory
                return __cpu_get_ioreq();
@@ -417,7 +420,6 @@
 void
 destroy_vmx_domain(void)
 {
-    extern int domid;
     extern FILE* logfile;
     char destroy_cmd[20];
     sprintf(destroy_cmd, "xm destroy %d", domid);
@@ -485,9 +487,9 @@
 #endif
                if (env->send_event) {
                        int ret;
-                       ret = xc_evtchn_send(xc_handle, ioreq_port);
+                       ret = xc_evtchn_send(xc_handle, ioreq_local_port);
                        if (ret == -1) {
-                               fprintf(logfile, "evtchn_send failed on port: 
%d\n", ioreq_port);
+                               fprintf(logfile, "evtchn_send failed on port: 
%d\n", ioreq_local_port);
                        }
                }
        }
@@ -499,7 +501,6 @@
 qemu_vmx_reset(void *unused)
 {
     char cmd[255];
-    extern int domid;
 
     /* pause domain first, to avoid repeated reboot request*/ 
     xc_domain_pause (xc_handle, domid);
@@ -512,6 +513,8 @@
 cpu_init()
 {
        CPUX86State *env;
+       struct ioctl_evtchn_bind_interdomain bind;
+       int rc;
       
         cpu_exec_init();
         qemu_register_reset(qemu_vmx_reset, NULL);
@@ -532,12 +535,14 @@
                return NULL;
        }
 
-       fprintf(logfile, "listening to port: %d\n", ioreq_port);
-       /*unmask the wanted port -- bind*/
-       if (ioctl(evtchn_fd, ('E'<<8)|2, ioreq_port) == -1) {
+       bind.remote_domain = domid;
+       bind.remote_port   = ioreq_remote_port;
+       rc = ioctl(evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+       if (rc == -1) {
                perror("ioctl");
                return NULL;
        }
+       ioreq_local_port = rc;
 
        return env;
 }
diff -r cd228621e1fd -r 4083eb31def0 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Thu Oct  6 14:12:31 2005
+++ b/tools/ioemu/vl.c  Thu Oct  6 15:07:52 2005
@@ -2806,9 +2806,9 @@
 
             case QEMU_OPTION_p:
                 {
-                  extern short ioreq_port;
-                  ioreq_port = atoi(optarg);
-                  printf("port: %d\n", ioreq_port);
+                  extern short ioreq_remote_port;
+                  ioreq_remote_port = atoi(optarg);
+                  printf("port: %d\n", ioreq_remote_port);
                 }
                 break;
             case QEMU_OPTION_l:
diff -r cd228621e1fd -r 4083eb31def0 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu Oct  6 14:12:31 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Thu Oct  6 15:07:52 2005
@@ -435,10 +435,10 @@
     u32 dom = DOMID_SELF, remote_dom;
     int port = 0;
 
-    static char *kwd_list[] = { "remote_dom", "dom", "port", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
-                                      &remote_dom, &dom, &port) )
+    static char *kwd_list[] = { "remote_dom", "dom", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
+                                      &remote_dom, &dom) )
         return NULL;
 
     if ( xc_evtchn_alloc_unbound(xc->xc_handle, remote_dom, dom, &port) != 0 )
diff -r cd228621e1fd -r 4083eb31def0 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Thu Oct  6 14:12:31 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py   Thu Oct  6 15:07:52 2005
@@ -126,8 +126,8 @@
             raise XendError(
                 "not a valid guest state file: pfn count out of range")
 
-        store_evtchn = dominfo.store_channel.port2
-        console_evtchn = dominfo.console_channel.port2
+        store_evtchn = dominfo.store_channel
+        console_evtchn = dominfo.console_channel
 
         cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
                str(dominfo.getDomid()), str(nr_pfns),
@@ -146,7 +146,7 @@
                           dominfo.getDomainPath())
                 IntroduceDomain(dominfo.getDomid(),
                                 store_mfn,
-                                dominfo.store_channel.port1,
+                                dominfo.store_channel,
                                 dominfo.getDomainPath())
             else:
                 m = re.match(r"^(console-mfn) (\d+)$", line)
diff -r cd228621e1fd -r 4083eb31def0 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Oct  6 14:12:31 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Oct  6 15:07:52 2005
@@ -31,8 +31,6 @@
 
 import xen.lowlevel.xc
 from xen.util.blkif import blkdev_uname_to_file
-
-from xen.xend.server import channel
 
 from xen.xend import image
 from xen.xend import scheduler
@@ -785,32 +783,6 @@
                           self.domid, self.info['name'])
 
 
-    def closeChannel(self, chan, entry):
-        """Close the given channel, if set, and remove the given entry in the
-        store.  Nothrow guarantee."""
-        
-        if chan:
-            chan.close()
-        try:
-            self.removeDom(entry)
-        except:
-            log.exception('Removing entry %s failed', entry)
-        
-
-    def closeStoreChannel(self):
-        """Close the store channel, if any.  Nothrow guarantee."""
-
-        self.closeChannel(self.store_channel, "store/port")
-        self.store_channel = None
-
-
-    def closeConsoleChannel(self):
-        """Close the console channel, if any.  Nothrow guarantee."""
-
-        self.closeChannel(self.console_channel, "console/port")
-        self.console_channel = None
-
-
     ## public:
 
     def setConsoleRef(self, ref):
@@ -960,12 +932,8 @@
             sxpr.append(['up_time', str(up_time) ])
             sxpr.append(['start_time', str(self.info['start_time']) ])
 
-        if self.store_channel:
-            sxpr.append(self.store_channel.sxpr())
         if self.store_mfn:
             sxpr.append(['store_mfn', self.store_mfn])
-        if self.console_channel:
-            sxpr.append(['console_channel', self.console_channel.sxpr()])
         if self.console_mfn:
             sxpr.append(['console_mfn', self.console_mfn])
 
@@ -1073,7 +1041,7 @@
         self.create_channel()
         self.image.createImage()
         IntroduceDomain(self.domid, self.store_mfn,
-                        self.store_channel.port1, self.dompath)
+                        self.store_channel, self.dompath)
 
 
     ## public:
@@ -1083,8 +1051,6 @@
         guarantee."""
 
         self.release_devices()
-        self.closeStoreChannel()
-        self.closeConsoleChannel()
 
         if self.image:
             try:
@@ -1164,35 +1130,22 @@
         
         @param path under which port is stored in db
         """
-        port = 0
         if path:
             try:
-                port = int(self.readDom(path))
+                return int(self.readDom(path))
             except:
                 # The port is not yet set, i.e. the channel has not yet been
                 # created.
                 pass
 
-        # Stale port information from above causes an Invalid Argument to be
-        # thrown by the eventChannel call below.  To recover, we throw away
-        # port if it turns out to be bad, and just create a new channel.
-        # If creating a new channel with two new ports fails, then something
-        # else is going wrong, so we bail.
-        while True:
-            try:
-                ret = channel.eventChannel(0, self.domid, port1 = port,
-                                           port2 = 0)
-                break
-            except:
-                log.exception("Exception in eventChannel(0, %d, %d, %d)",
-                              self.domid, port, 0)
-                if port == 0:
-                    raise
-                else:
-                    port = 0
-                    log.error("Recovering from above exception.")
-        self.storeDom(path, ret.port1)
-        return ret
+        try:
+            port = xc.evtchn_alloc_unbound(dom=self.domid, remote_dom=0)
+        except:
+            log.exception("Exception in alloc_unbound(%d)", self.domid)
+            raise
+
+        self.storeDom(path, port)
+        return port
 
     def create_channel(self):
         """Create the channels to the domain.
@@ -1419,11 +1372,11 @@
 
 
     def initStoreConnection(self):
-        ref = xc.init_store(self.store_channel.port2)
+        ref = xc.init_store(self.store_channel)
         if ref and ref >= 0:
             self.setStoreRef(ref)
             try:
-                IntroduceDomain(self.domid, ref, self.store_channel.port1,
+                IntroduceDomain(self.domid, ref, self.store_channel,
                                 self.dompath)
             except RuntimeError, ex:
                 if ex.args[0] == errno.EISCONN:
diff -r cd228621e1fd -r 4083eb31def0 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Thu Oct  6 14:12:31 2005
+++ b/tools/python/xen/xend/image.py    Thu Oct  6 15:07:52 2005
@@ -25,8 +25,6 @@
 from xen.xend.XendError import VmError
 from xen.xend.XendLogging import log
 
-from xen.xend.server import channel
-
 
 xc = xen.lowlevel.xc.new()
 
@@ -168,11 +166,11 @@
 
     def buildDomain(self):
         if self.vm.store_channel:
-            store_evtchn = self.vm.store_channel.port2
+            store_evtchn = self.vm.store_channel
         else:
             store_evtchn = 0
         if self.vm.console_channel:
-            console_evtchn = self.vm.console_channel.port2
+            console_evtchn = self.vm.console_channel
         else:
             console_evtchn = 0
 
@@ -228,16 +226,17 @@
 
     def buildDomain(self):
         # Create an event channel
-        self.device_channel = channel.eventChannel(0, self.vm.getDomid())
-        log.info("VMX device model port: %d", self.device_channel.port2)
+        self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
+                                                      remote_dom=0)
+        log.info("VMX device model port: %d", self.device_channel)
         if self.vm.store_channel:
-            store_evtchn = self.vm.store_channel.port2
+            store_evtchn = self.vm.store_channel
         else:
             store_evtchn = 0
 
         log.debug("dom            = %d", self.vm.getDomid())
         log.debug("image          = %s", self.kernel)
-        log.debug("control_evtchn = %d", self.device_channel.port2)
+        log.debug("control_evtchn = %d", self.device_channel)
         log.debug("store_evtchn   = %d", store_evtchn)
         log.debug("memsize        = %d", self.vm.getMemoryTarget() / 1024)
         log.debug("flags          = %d", self.flags)
@@ -245,7 +244,7 @@
 
         ret = xc.vmx_build(dom            = self.vm.getDomid(),
                            image          = self.kernel,
-                           control_evtchn = self.device_channel.port2,
+                           control_evtchn = self.device_channel,
                            store_evtchn   = store_evtchn,
                            memsize        = self.vm.getMemoryTarget() / 1024,
                            flags          = self.flags,
@@ -334,7 +333,7 @@
         if len(vnc):
             args = args + vnc
         args = args + ([ "-d",  "%d" % self.vm.getDomid(),
-                  "-p", "%d" % self.device_channel.port1,
+                  "-p", "%d" % self.device_channel,
                   "-m", "%s" % (self.vm.getMemoryTarget() / 1024)])
         args = args + self.dmargs
         env = dict(os.environ)
@@ -358,8 +357,6 @@
         return vncconnect
 
     def destroy(self):
-        if self.device_channel:
-            self.device_channel.close()
         import signal
         if not self.pid:
             return
diff -r cd228621e1fd -r 4083eb31def0 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Thu Oct  6 14:12:31 2005
+++ b/tools/xenstore/xenstored_domain.c Thu Oct  6 15:07:52 2005
@@ -36,6 +36,8 @@
 #include "xenstored_watch.h"
 #include "xenstored_test.h"
 
+#include <xen/linux/evtchn.h>
+
 static int *xc_handle;
 static int eventchn_fd;
 static int virq_port;
@@ -76,9 +78,6 @@
        u8 flags;
        char buf[0];
 } __attribute__((packed));
-
-#define EVENTCHN_BIND          _IO('E', 2)
-#define EVENTCHN_UNBIND        _IO('E', 3)
 
 /* FIXME: Mark connection as broken (close it?) when this happens. */
 static bool check_buffer(const struct ringbuf_head *h)
@@ -207,14 +206,17 @@
 static int destroy_domain(void *_domain)
 {
        struct domain *domain = _domain;
+       struct ioctl_evtchn_unbind unbind;
 
        list_del(&domain->list);
 
-       if (domain->port &&
-           (ioctl(eventchn_fd, EVENTCHN_UNBIND, domain->port) != 0))
-               eprintf("> Unbinding port %i failed!\n", domain->port);
-
-       if(domain->page)
+       if (domain->port) {
+               unbind.port = domain->port;
+               if (ioctl(eventchn_fd, IOCTL_EVTCHN_UNBIND, &unbind) == -1)
+                       eprintf("> Unbinding port %i failed!\n", domain->port);
+       }
+
+       if (domain->page)
                munmap(domain->page, getpagesize());
 
        return 0;
@@ -278,6 +280,9 @@
                                 const char *path)
 {
        struct domain *domain;
+       struct ioctl_evtchn_bind_interdomain bind;
+       int rc;
+
        domain = talloc(context, struct domain);
        domain->port = 0;
        domain->shutdown = 0;
@@ -298,10 +303,13 @@
        domain->output = domain->page + getpagesize()/2;
 
        /* Tell kernel we're interested in this event. */
-       if (ioctl(eventchn_fd, EVENTCHN_BIND, port) != 0)
+       bind.remote_domain = domid;
+       bind.remote_port   = port;
+       rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+       if (rc == -1)
                return NULL;
 
-       domain->port = port;
+       domain->port = rc;
        domain->conn = new_connection(writechn, readchn);
        domain->conn->domain = domain;
        return domain;
@@ -445,6 +453,8 @@
 int domain_init(void)
 {
        struct stat st;
+       struct ioctl_evtchn_bind_virq bind;
+       int rc;
 
        /* The size of the ringbuffer: half a page minus head structure. */
        ringbuf_datasize = getpagesize() / 2 - sizeof(struct ringbuf_head);
@@ -482,11 +492,11 @@
        if (eventchn_fd < 0)
                barf_perror("Failed to open evtchn device");
 
-       if (xc_evtchn_bind_virq(*xc_handle, VIRQ_DOM_EXC, &virq_port))
-               barf_perror("Failed to bind to domain exception virq");
-
-       if (ioctl(eventchn_fd, EVENTCHN_BIND, virq_port) != 0)
+       bind.virq = VIRQ_DOM_EXC;
+       rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
+       if (rc == -1)
                barf_perror("Failed to bind to domain exception virq port");
+       virq_port = rc;
 
        return eventchn_fd;
 }
diff -r cd228621e1fd -r 4083eb31def0 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Thu Oct  6 14:12:31 2005
+++ b/xen/common/event_channel.c        Thu Oct  6 15:07:52 2005
@@ -36,7 +36,13 @@
 #define evtchn_from_port(d,p) \
     (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)])
 
-#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 )
+#define ERROR_EXIT(_errno)                                          \
+    do {                                                            \
+        DPRINTK("EVTCHNOP failure: domain %d, error %d, line %d\n", \
+                current->domain->domain_id, (_errno), __LINE__);    \
+        rc = (_errno);                                              \
+        goto out;                                                   \
+    } while ( 0 )
 
 static int get_free_port(struct domain *d)
 {
diff -r cd228621e1fd -r 4083eb31def0 
linux-2.6-xen-sparse/include/asm-xen/linux-public/evtchn.h
--- /dev/null   Thu Oct  6 14:12:31 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/evtchn.h        Thu Oct 
 6 15:07:52 2005
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * evtchn.h
+ * 
+ * Interface to /dev/xen/evtchn.
+ * 
+ * Copyright (c) 2003-2005, K A Fraser
+ * 
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __LINUX_PUBLIC_EVTCHN_H__
+#define __LINUX_PUBLIC_EVTCHN_H__
+
+/* /dev/xen/evtchn resides at device number major=10, minor=201 */
+#define EVTCHN_MINOR 201
+
+/*
+ * Bind a fresh port to VIRQ @virq.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_VIRQ                         \
+       _IOC(_IOC_NONE, 'E', 0, sizeof(struct ioctl_evtchn_bind_virq))
+struct ioctl_evtchn_bind_virq {
+       unsigned int virq;
+};
+
+/*
+ * Bind a fresh port to remote <@remote_domain, @remote_port>.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_INTERDOMAIN                  \
+       _IOC(_IOC_NONE, 'E', 1, sizeof(struct ioctl_evtchn_bind_interdomain))
+struct ioctl_evtchn_bind_interdomain {
+       unsigned int remote_domain, remote_port;
+};
+
+/*
+ * Allocate a fresh port for binding to @remote_domain.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_UNBOUND_PORT                 \
+       _IOC(_IOC_NONE, 'E', 2, sizeof(struct ioctl_evtchn_bind_unbound_port))
+struct ioctl_evtchn_bind_unbound_port {
+       unsigned int remote_domain;
+};
+
+/*
+ * Unbind previously allocated @port.
+ */
+#define IOCTL_EVTCHN_UNBIND                            \
+       _IOC(_IOC_NONE, 'E', 3, sizeof(struct ioctl_evtchn_unbind))
+struct ioctl_evtchn_unbind {
+       unsigned int port;
+};
+
+/* Clear and reinitialise the event buffer. Clear error condition. */
+#define IOCTL_EVTCHN_RESET                             \
+       _IOC(_IOC_NONE, 'E', 4, 0)
+
+#endif /* __LINUX_PUBLIC_EVTCHN_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r cd228621e1fd -r 4083eb31def0 tools/python/xen/xend/server/channel.py
--- a/tools/python/xen/xend/server/channel.py   Thu Oct  6 14:12:31 2005
+++ /dev/null   Thu Oct  6 15:07:52 2005
@@ -1,76 +0,0 @@
-#============================================================================
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of version 2.1 of the GNU Lesser General Public
-# License as published by the Free Software Foundation.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#============================================================================
-# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
-# Copyright (C) 2005 XenSource Ltd
-#============================================================================
-
-import xen.lowlevel.xc
-
-from xen.xend.XendLogging import log
-
-
-xc = xen.lowlevel.xc.new()
-
-
-class EventChannel:
-    """An event channel between domains.
-    """
-
-    def __init__(self, dom1, dom2, port1, port2):
-        self.dom1 = dom1
-        self.dom2 = dom2
-        self.port1 = port1
-        self.port2 = port2
-
-
-    def close(self):
-        """Close the event channel.  Nothrow guarantee.
-        """
-        def evtchn_close(dom, port):
-            try:
-                xc.evtchn_close(dom=dom, port=port)
-            except Exception:
-                log.exception("Exception closing event channel %d, %d.", dom,
-                              port)
-            
-        evtchn_close(self.dom1, self.port1)
-        evtchn_close(self.dom2, self.port2)
-
-
-    def sxpr(self):
-        return ['event-channel',
-                ['dom1',  self.dom1  ],
-                ['port1', self.port1 ],
-                ['dom2',  self.dom2  ],
-                ['port2', self.port2 ]
-                ]
-
-
-    def __repr__(self):
-        return ("<EventChannel dom1:%d:%d dom2:%d:%d>"
-                % (self.dom1, self.port1, self.dom2, self.port2))
-
-
-def eventChannel(dom1, dom2, port1 = 0, port2 = 0):
-    """Create an event channel between domains.
-        
-    @return EventChannel (None on error)
-    """
-    v = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2,
-                                   port1=port1, port2=port2)
-    if v and v.get('port1'):
-        return EventChannel(dom1, dom2, v['port1'], v['port2'])
-    else:
-        return None

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Change how event channels are allocated and used by the control, Xen patchbot -unstable <=