libxl: make libxl_device_pci_{add,remove,destroy} interfaces asynchronous
authorIan Campbell <ian.campbell@citrix.com>
Fri, 3 Aug 2012 08:54:03 +0000 (09:54 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 3 Aug 2012 08:54:03 +0000 (09:54 +0100)
This does not make the implementation fully asynchronous but just
updates the API to support asynchrony in the future.

Currently although these functions do not call hotplug scripts etc and
therefore are not "slow" (per the comment about ao machinery in
libxl_internal.h) they do interact with the device model and so are
not quite "fast" either. We can live with this for now.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
tools/libxl/libxl.h
tools/libxl/libxl_pci.c
tools/libxl/xl_cmdimpl.c
tools/ocaml/libs/xl/xenlight_stubs.c
tools/python/xen/lowlevel/xl/xl.c

index 5ec2d749f77238255ff1d34ccb519c7d64559c85..cc74e1359f95e12975b9b1faf66e3f44c9e5844f 100644 (file)
@@ -757,10 +757,21 @@ int libxl_device_vfb_destroy(libxl_ctx *ctx, uint32_t domid,
                              LIBXL_EXTERNAL_CALLERS_ONLY;
 
 /* PCI Passthrough */
-int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev);
-int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev);
-int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev);
-libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int *num);
+int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
+                         libxl_device_pci *pcidev,
+                         const libxl_asyncop_how *ao_how)
+                         LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
+                            libxl_device_pci *pcidev,
+                            const libxl_asyncop_how *ao_how)
+                            LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
+                             libxl_device_pci *pcidev,
+                             const libxl_asyncop_how *ao_how)
+                             LIBXL_EXTERNAL_CALLERS_ONLY;
+
+libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid,
+                                        int *num);
 
 /*
  * Functions related to making devices assignable -- that is, bound to
index 9c92ae61a5cb2b4acb2d45b181b26dd00db40d27..48986f3fa8d5b028a43cef1f087537103e2c5f39 100644 (file)
@@ -1010,13 +1010,15 @@ int libxl__device_pci_setdefault(libxl__gc *gc, libxl_device_pci *pci)
     return 0;
 }
 
-int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
+int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
+                         libxl_device_pci *pcidev,
+                         const libxl_asyncop_how *ao_how)
 {
-    GC_INIT(ctx);
+    AO_CREATE(ctx, domid, ao_how);
     int rc;
     rc = libxl__device_pci_add(gc, domid, pcidev, 0);
-    GC_FREE;
-    return rc;
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
 }
 
 static int libxl_pcidev_assignable(libxl_ctx *ctx, libxl_device_pci *pcidev)
@@ -1150,6 +1152,9 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
     return 0;
 }
 
+static int libxl__device_pci_remove_common(libxl__gc *gc, uint32_t domid,
+                                           libxl_device_pci *pcidev, int force);
+
 static int do_pci_remove(libxl__gc *gc, uint32_t domid,
                          libxl_device_pci *pcidev, int force)
 {
@@ -1263,10 +1268,7 @@ out:
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
         libxl_device_pci pcidev_s = *pcidev;
-        if (force)
-                libxl_device_pci_destroy(ctx, stubdomid, &pcidev_s);
-        else
-                libxl_device_pci_remove(ctx, stubdomid, &pcidev_s);
+        libxl__device_pci_remove_common(gc, stubdomid, &pcidev_s, force);
     }
 
     libxl__device_pci_remove_xenstore(gc, domid, pcidev);
@@ -1313,27 +1315,31 @@ out:
     return rc;
 }
 
-int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
+int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
+                            libxl_device_pci *pcidev,
+                            const libxl_asyncop_how *ao_how)
+
 {
-    GC_INIT(ctx);
+    AO_CREATE(ctx, domid, ao_how);
     int rc;
 
     rc = libxl__device_pci_remove_common(gc, domid, pcidev, 0);
 
-    GC_FREE;
-    return rc;
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
 }
 
 int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
-                                  libxl_device_pci *pcidev)
+                             libxl_device_pci *pcidev,
+                             const libxl_asyncop_how *ao_how)
 {
-    GC_INIT(ctx);
+    AO_CREATE(ctx, domid, ao_how);
     int rc;
 
     rc = libxl__device_pci_remove_common(gc, domid, pcidev, 1);
 
-    GC_FREE;
-    return rc;
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
 }
 
 static void libxl__device_pci_from_xs_be(libxl__gc *gc,
@@ -1415,7 +1421,7 @@ int libxl__device_pci_destroy_all(libxl__gc *gc, uint32_t domid)
          * respond to SCI interrupt because the guest kernel has shut down the
          * devices by the time we even get here!
          */
-        if (libxl_device_pci_destroy(ctx, domid, pcidevs + i) < 0)
+        if (libxl__device_pci_remove_common(gc, domid, pcidevs + i, 1) < 0)
             rc = ERROR_FAIL;
     }
 
index a7dc3403d1931c5209be3c0291c742de026e28ec..138cd72b80fe0a1a4d925c7448129544596ef746 100644 (file)
@@ -2389,9 +2389,9 @@ static void pcidetach(const char *dom, const char *bdf, int force)
         exit(2);
     }
     if (force)
-        libxl_device_pci_destroy(ctx, domid, &pcidev);
+        libxl_device_pci_destroy(ctx, domid, &pcidev, 0);
     else
-        libxl_device_pci_remove(ctx, domid, &pcidev);
+        libxl_device_pci_remove(ctx, domid, &pcidev, 0);
 
     libxl_device_pci_dispose(&pcidev);
     xlu_cfg_destroy(config);
@@ -2435,7 +2435,7 @@ static void pciattach(const char *dom, const char *bdf, const char *vs)
         fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
-    libxl_device_pci_add(ctx, domid, &pcidev);
+    libxl_device_pci_add(ctx, domid, &pcidev, 0);
 
     libxl_device_pci_dispose(&pcidev);
     xlu_cfg_destroy(config);
index adda67f54f0cc0a0ba93457ab390ff656f5403cd..5f19a82c8b68b163a2c96289bdbc7f8fc059a4b7 100644 (file)
@@ -423,7 +423,7 @@ value stub_xl_device_pci_add(value info, value domid)
        device_pci_val(&gc, &lg, &c_info, info);
 
        INIT_CTX();
-       ret = libxl_device_pci_add(ctx, Int_val(domid), &c_info);
+       ret = libxl_device_pci_add(ctx, Int_val(domid), &c_info, 0);
        if (ret != 0)
                failwith_xl("pci_add", &lg);
        FREE_CTX();
@@ -441,7 +441,7 @@ value stub_xl_device_pci_remove(value info, value domid)
        device_pci_val(&gc, &lg, &c_info, info);
 
        INIT_CTX();
-       ret = libxl_device_pci_remove(ctx, Int_val(domid), &c_info);
+       ret = libxl_device_pci_remove(ctx, Int_val(domid), &c_info, 0);
        if (ret != 0)
                failwith_xl("pci_remove", &lg);
        FREE_CTX();
index 553fc5887179921818b1b11e518e8ef6dfcc862a..0551c7636f3a846119b56fa5c740bc00160caebe 100644 (file)
@@ -497,7 +497,7 @@ static PyObject *pyxl_pci_add(XlObject *self, PyObject *args)
         return NULL;
     }
     pci = (Py_device_pci *)obj;
-    if ( libxl_device_pci_add(self->ctx, domid, &pci->obj) ) {
+    if ( libxl_device_pci_add(self->ctx, domid, &pci->obj, 0) ) {
         PyErr_SetString(xl_error_obj, "cannot add pci device");
         return NULL;
     }
@@ -519,12 +519,12 @@ static PyObject *pyxl_pci_del(XlObject *self, PyObject *args)
     }
     pci = (Py_device_pci *)obj;
     if ( force ) {
-        if ( libxl_device_pci_destroy(self->ctx, domid, &pci->obj) ) {
+        if ( libxl_device_pci_destroy(self->ctx, domid, &pci->obj, 0) ) {
             PyErr_SetString(xl_error_obj, "cannot remove pci device");
             return NULL;
         }
     } else {
-        if ( libxl_device_pci_remove(self->ctx, domid, &pci->obj) ) {
+        if ( libxl_device_pci_remove(self->ctx, domid, &pci->obj, 0) ) {
             PyErr_SetString(xl_error_obj, "cannot remove pci device");
             return NULL;
         }