Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/xen/xen Move the connection code of xbdback(4) and ...



details:   https://anonhg.NetBSD.org/src/rev/8261f2a903f3
branches:  trunk
changeset: 764665:8261f2a903f3
user:      jym <jym%NetBSD.org@localhost>
date:      Fri Apr 29 22:58:46 2011 +0000

description:
Move the connection code of xbdback(4) and xvif(4) backends in separate
functions. The frontend watch function is easier to read, and mixing
switch() with goto's error paths is rather error-prone.

While here, sprinkle some aprint_*.

Tested under amd64 dom0 with i386 PAE and amd64 domUs.

diffstat:

 sys/arch/xen/xen/xbdback_xenbus.c    |  276 ++++++++++++++++---------------
 sys/arch/xen/xen/xennetback_xenbus.c |  305 +++++++++++++++++++---------------
 2 files changed, 310 insertions(+), 271 deletions(-)

diffs (truncated from 664 to 300 lines):

diff -r e32e3e2f5bb8 -r 8261f2a903f3 sys/arch/xen/xen/xbdback_xenbus.c
--- a/sys/arch/xen/xen/xbdback_xenbus.c Fri Apr 29 22:57:54 2011 +0000
+++ b/sys/arch/xen/xen/xbdback_xenbus.c Fri Apr 29 22:58:46 2011 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: xbdback_xenbus.c,v 1.33 2011/03/05 15:12:16 bouyer Exp $      */
+/*      $NetBSD: xbdback_xenbus.c,v 1.34 2011/04/29 22:58:46 jym Exp $      */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xbdback_xenbus.c,v 1.33 2011/03/05 15:12:16 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xbdback_xenbus.c,v 1.34 2011/04/29 22:58:46 jym Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -479,20 +479,152 @@
        return 0;
 }
 
+static int
+xbdback_connect(struct xbdback_instance *xbdi)
+{
+       int len, err;
+       struct gnttab_map_grant_ref grop;
+       struct gnttab_unmap_grant_ref ungrop;
+       evtchn_op_t evop;
+       u_long ring_ref, revtchn;
+       char *xsproto;
+       char evname[16];
+       const char *proto;
+       struct xenbus_device *xbusd = xbdi->xbdi_xbusd;
+
+       /* read comunication informations */
+       err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
+           "ring-ref", &ring_ref, 10);
+       if (err) {
+               xenbus_dev_fatal(xbusd, err, "reading %s/ring-ref",
+                   xbusd->xbusd_otherend);
+               return -1;
+       }
+       err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
+           "event-channel", &revtchn, 10);
+       if (err) {
+               xenbus_dev_fatal(xbusd, err, "reading %s/event-channel",
+                   xbusd->xbusd_otherend);
+               return -1;
+       }
+       err = xenbus_read(NULL, xbusd->xbusd_otherend, "protocol",
+           &len, &xsproto);
+       if (err) {
+               xbdi->xbdi_proto = XBDIP_NATIVE;
+               proto = "unspecified";
+       } else {
+               if (strcmp(xsproto, XEN_IO_PROTO_ABI_NATIVE) == 0) {
+                       xbdi->xbdi_proto = XBDIP_NATIVE;
+                       proto = XEN_IO_PROTO_ABI_NATIVE;
+               } else if (strcmp(xsproto, XEN_IO_PROTO_ABI_X86_32) == 0) {
+                       xbdi->xbdi_proto = XBDIP_32;
+                       proto = XEN_IO_PROTO_ABI_X86_32;
+               } else if (strcmp(xsproto, XEN_IO_PROTO_ABI_X86_64) == 0) {
+                       xbdi->xbdi_proto = XBDIP_64;
+                       proto = XEN_IO_PROTO_ABI_X86_64;
+               } else {
+                       aprint_error("xbd domain %d: unknown proto %s\n",
+                           xbdi->xbdi_domid, xsproto);
+                       free(xsproto, M_DEVBUF);
+                       return -1;
+               }
+       }
+       free(xsproto, M_DEVBUF);
+
+       /* allocate VA space and map rings */
+       xbdi->xbdi_ring_va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
+           UVM_KMF_VAONLY);
+       if (xbdi->xbdi_ring_va == 0) {
+               xenbus_dev_fatal(xbusd, ENOMEM,
+                   "can't get VA for ring", xbusd->xbusd_otherend);
+               return -1;
+       }
+
+       grop.host_addr = xbdi->xbdi_ring_va;
+       grop.flags = GNTMAP_host_map;
+       grop.ref = ring_ref;
+       grop.dom = xbdi->xbdi_domid;
+       err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+           &grop, 1);
+       if (err || grop.status) {
+               aprint_error("xbdback %s: can't map grant ref: %d/%d\n",
+                   xbusd->xbusd_path, err, grop.status);
+               xenbus_dev_fatal(xbusd, EINVAL,
+                   "can't map ring", xbusd->xbusd_otherend);
+               goto err;
+       }
+       xbdi->xbdi_ring_handle = grop.handle;
+
+       switch(xbdi->xbdi_proto) {
+       case XBDIP_NATIVE:
+       {
+               blkif_sring_t *sring = (void *)xbdi->xbdi_ring_va;
+               BACK_RING_INIT(&xbdi->xbdi_ring.ring_n, sring, PAGE_SIZE);
+               break;
+       }
+       case XBDIP_32:
+       {
+               blkif_x86_32_sring_t *sring = (void *)xbdi->xbdi_ring_va;
+               BACK_RING_INIT(&xbdi->xbdi_ring.ring_32, sring, PAGE_SIZE);
+               break;
+       }
+       case XBDIP_64:
+       {
+               blkif_x86_64_sring_t *sring = (void *)xbdi->xbdi_ring_va;
+               BACK_RING_INIT(&xbdi->xbdi_ring.ring_64, sring, PAGE_SIZE);
+               break;
+       }
+       }
+
+       evop.cmd = EVTCHNOP_bind_interdomain;
+       evop.u.bind_interdomain.remote_dom = xbdi->xbdi_domid;
+       evop.u.bind_interdomain.remote_port = revtchn;
+       err = HYPERVISOR_event_channel_op(&evop);
+       if (err) {
+               aprint_error("blkback %s: "
+                   "can't get event channel: %d\n",
+                   xbusd->xbusd_otherend, err);
+               xenbus_dev_fatal(xbusd, err,
+                   "can't bind event channel", xbusd->xbusd_otherend);
+               goto err2;
+       }
+       xbdi->xbdi_evtchn = evop.u.bind_interdomain.local_port;
+
+       snprintf(evname, sizeof(evname), "xbd%d.%d",
+           xbdi->xbdi_domid, xbdi->xbdi_handle);
+       event_set_handler(xbdi->xbdi_evtchn, xbdback_evthandler,
+           xbdi, IPL_BIO, evname);
+       aprint_verbose("xbd backend 0x%x for domain %d "
+           "using event channel %d, protocol %s\n", xbdi->xbdi_handle,
+           xbdi->xbdi_domid, xbdi->xbdi_evtchn, proto);
+       hypervisor_enable_event(xbdi->xbdi_evtchn);
+       hypervisor_notify_via_evtchn(xbdi->xbdi_evtchn);
+       xbdi->xbdi_status = CONNECTED;
+       return 0;
+
+err2:
+       /* unmap ring */
+       ungrop.host_addr = xbdi->xbdi_ring_va;
+       ungrop.handle = xbdi->xbdi_ring_handle;
+       ungrop.dev_bus_addr = 0;
+       err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
+           &ungrop, 1);
+       if (err)
+           aprint_error("xbdback %s: unmap_grant_ref failed: %d\n",
+               xbusd->xbusd_path, err);
+
+err:
+       /* free ring VA space */
+       uvm_km_free(kernel_map, xbdi->xbdi_ring_va, PAGE_SIZE, UVM_KMF_VAONLY);
+       return -1;
+}
+
 static void
 xbdback_frontend_changed(void *arg, XenbusState new_state)
 {
        struct xbdback_instance *xbdi = arg;
        struct xenbus_device *xbusd = xbdi->xbdi_xbusd;
-       u_long ring_ref, revtchn;
-       struct gnttab_map_grant_ref grop;
-       struct gnttab_unmap_grant_ref ungrop;
-       evtchn_op_t evop;
-       char evname[16];
-       const char *proto;
-       char *xsproto;
-       int len;
-       int err, s;
+       int s;
 
        XENPRINTF(("xbdback %s: new state %d\n", xbusd->xbusd_path, new_state));
        switch(new_state) {
@@ -502,114 +634,7 @@
        case XenbusStateConnected:
                if (xbdi->xbdi_status == CONNECTED)
                        break;
-               /* read comunication informations */
-               err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
-                   "ring-ref", &ring_ref, 10);
-               if (err) {
-                       xenbus_dev_fatal(xbusd, err, "reading %s/ring-ref",
-                           xbusd->xbusd_otherend);
-                       break;
-               }
-               err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
-                   "event-channel", &revtchn, 10);
-               if (err) {
-                       xenbus_dev_fatal(xbusd, err, "reading %s/event-channel",
-                           xbusd->xbusd_otherend);
-                       break;
-               }
-               err = xenbus_read(NULL, xbusd->xbusd_otherend, "protocol",
-                   &len, &xsproto);
-               if (err) {
-                       proto = "unspecified";
-                       xbdi->xbdi_proto = XBDIP_NATIVE;
-               } else {
-                       if(strcmp(xsproto, XEN_IO_PROTO_ABI_NATIVE) == 0) {
-                               xbdi->xbdi_proto = XBDIP_NATIVE;
-                               proto = XEN_IO_PROTO_ABI_NATIVE;
-                       } else if(strcmp(xsproto, XEN_IO_PROTO_ABI_X86_32) == 0) {
-                               xbdi->xbdi_proto = XBDIP_32;
-                               proto = XEN_IO_PROTO_ABI_X86_32;
-                       } else if(strcmp(xsproto, XEN_IO_PROTO_ABI_X86_64) == 0) {
-                               xbdi->xbdi_proto = XBDIP_64;
-                               proto = XEN_IO_PROTO_ABI_X86_64;
-                       } else {
-                               printf("xbd domain %d: unknown proto %s\n",
-                                   xbdi->xbdi_domid, xsproto);
-                               free(xsproto, M_DEVBUF);
-                               return;
-                       }
-                       free(xsproto, M_DEVBUF);
-               }
-               /* allocate VA space and map rings */
-               xbdi->xbdi_ring_va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
-                   UVM_KMF_VAONLY);
-               if (xbdi->xbdi_ring_va == 0) {
-                       xenbus_dev_fatal(xbusd, ENOMEM,
-                           "can't get VA for ring", xbusd->xbusd_otherend);
-                       break;
-               }
-               grop.host_addr = xbdi->xbdi_ring_va;
-               grop.flags = GNTMAP_host_map;
-               grop.ref = ring_ref;
-               grop.dom = xbdi->xbdi_domid;
-               err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
-                   &grop, 1);
-               if (err || grop.status) {
-                       printf("xbdback %s: can't map grant ref: %d/%d\n",
-                           xbusd->xbusd_path, err, grop.status);
-                       xenbus_dev_fatal(xbusd, EINVAL,
-                           "can't map ring", xbusd->xbusd_otherend);
-                       goto err;
-               }
-               xbdi->xbdi_ring_handle = grop.handle;
-               switch(xbdi->xbdi_proto) {
-               case XBDIP_NATIVE:
-               {
-                       blkif_sring_t *sring = (void *)xbdi->xbdi_ring_va;
-                       BACK_RING_INIT(&xbdi->xbdi_ring.ring_n,
-                           sring, PAGE_SIZE);
-                       break;
-               }
-               case XBDIP_32:
-               {
-                       blkif_x86_32_sring_t *sring =
-                           (void *)xbdi->xbdi_ring_va;
-                       BACK_RING_INIT(&xbdi->xbdi_ring.ring_32,
-                           sring, PAGE_SIZE);
-                       break;
-               }
-               case XBDIP_64:
-               {
-                       blkif_x86_64_sring_t *sring =
-                           (void *)xbdi->xbdi_ring_va;
-                       BACK_RING_INIT(&xbdi->xbdi_ring.ring_64,
-                           sring, PAGE_SIZE);
-                       break;
-               }
-               }
-               evop.cmd = EVTCHNOP_bind_interdomain;
-               evop.u.bind_interdomain.remote_dom = xbdi->xbdi_domid;
-               evop.u.bind_interdomain.remote_port = revtchn;
-               err = HYPERVISOR_event_channel_op(&evop);
-               if (err) {
-                       aprint_error("blkback %s: "
-                           "can't get event channel: %d\n",
-                           xbusd->xbusd_otherend, err);
-                       xenbus_dev_fatal(xbusd, err,
-                           "can't bind event channel", xbusd->xbusd_otherend);
-                       goto err2;
-               }
-               xbdi->xbdi_evtchn = evop.u.bind_interdomain.local_port;
-               snprintf(evname, sizeof(evname), "xbd%d.%d",
-                   xbdi->xbdi_domid, xbdi->xbdi_handle);
-               event_set_handler(xbdi->xbdi_evtchn, xbdback_evthandler,
-                   xbdi, IPL_BIO, evname);
-               aprint_verbose("xbd backend 0x%x for domain %d "
-                   "using event channel %d, protocol %s\n", xbdi->xbdi_handle,
-                   xbdi->xbdi_domid, xbdi->xbdi_evtchn, proto);
-               hypervisor_enable_event(xbdi->xbdi_evtchn);
-               hypervisor_notify_via_evtchn(xbdi->xbdi_evtchn);
-               xbdi->xbdi_status = CONNECTED;
+               xbdback_connect(xbdi);
                break;
        case XenbusStateClosing:
                hypervisor_mask_event(xbdi->xbdi_evtchn);
@@ -634,19 +659,6 @@
                    xbusd->xbusd_path, new_state);
        }
        return;



Home | Main Index | Thread Index | Old Index