>-----Original Message-----
>From: Steve Sistare <steven.sist...@oracle.com>
>Subject: [PATCH V3 36/42] vfio/iommufd: preserve descriptors
>
>Save the iommu and vfio device fd in CPR state when it is created.
>After CPR, the fd number is found in CPR state and reused.  Remember
>the reused status for subsequent patches.  The reused status is cleared
>when vmstate load finishes.
>
>Signed-off-by: Steve Sistare <steven.sist...@oracle.com>
>---
> backends/iommufd.c       | 19 ++++++++++---------
> hw/vfio/cpr-iommufd.c    | 16 ++++++++++++++++
> hw/vfio/device.c         | 10 ++--------
> hw/vfio/iommufd.c        | 13 +++++++++++--
> include/system/iommufd.h |  1 +
> 5 files changed, 40 insertions(+), 19 deletions(-)
>
>diff --git a/backends/iommufd.c b/backends/iommufd.c
>index 6fed1c1..492747c 100644
>--- a/backends/iommufd.c
>+++ b/backends/iommufd.c
>@@ -16,12 +16,18 @@
> #include "qemu/module.h"
> #include "qom/object_interfaces.h"
> #include "qemu/error-report.h"
>+#include "migration/cpr.h"
> #include "monitor/monitor.h"
> #include "trace.h"
> #include "hw/vfio/vfio-device.h"
> #include <sys/ioctl.h>
> #include <linux/iommufd.h>
>
>+static const char *iommufd_fd_name(IOMMUFDBackend *be)
>+{
>+    return object_get_canonical_path_component(OBJECT(be));
>+}
>+
> static void iommufd_backend_init(Object *obj)
> {
>     IOMMUFDBackend *be = IOMMUFD_BACKEND(obj);
>@@ -47,9 +53,8 @@ static void iommufd_backend_set_fd(Object *obj, const
>char *str, Error **errp)
>     IOMMUFDBackend *be = IOMMUFD_BACKEND(obj);
>     int fd = -1;
>
>-    fd = monitor_fd_param(monitor_cur(), str, errp);
>+    fd = cpr_get_fd_param(iommufd_fd_name(be), str, 0, &be->cpr_reused, errp);
>     if (fd == -1) {
>-        error_prepend(errp, "Could not parse remote object fd %s:", str);
>         return;
>     }
>     be->fd = fd;
>@@ -95,14 +100,9 @@ bool iommufd_change_process(IOMMUFDBackend *be,
>Error **errp)
>
> bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp)
> {
>-    int fd;
>-
>     if (be->owned && !be->users) {
>-        fd = qemu_open("/dev/iommu", O_RDWR, errp);
>-        if (fd < 0) {
>-            return false;
>-        }
>-        be->fd = fd;
>+        be->fd = cpr_open_fd("/dev/iommu", O_RDWR, iommufd_fd_name(be), 0,
>+                             &be->cpr_reused, errp);

Need to check error before assign to be->fd.

>     }
>     be->users++;
>
>@@ -121,6 +121,7 @@ void iommufd_backend_disconnect(IOMMUFDBackend
>*be)
>         be->fd = -1;
>     }
> out:
>+    cpr_delete_fd(iommufd_fd_name(be), 0);
>     trace_iommufd_backend_disconnect(be->fd, be->users);
> }
>
>diff --git a/hw/vfio/cpr-iommufd.c b/hw/vfio/cpr-iommufd.c
>index 46f2006..b760bd3 100644
>--- a/hw/vfio/cpr-iommufd.c
>+++ b/hw/vfio/cpr-iommufd.c
>@@ -8,6 +8,7 @@
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> #include "hw/vfio/vfio-cpr.h"
>+#include "hw/vfio/vfio-device.h"
> #include "migration/blocker.h"
> #include "migration/cpr.h"
> #include "migration/migration.h"
>@@ -25,10 +26,25 @@ static bool vfio_cpr_supported(VFIOIOMMUFDContainer
>*container, Error **errp)
>     return true;
> }
>
>+static int vfio_container_post_load(void *opaque, int version_id)
>+{
>+    VFIOIOMMUFDContainer *container = opaque;
>+    VFIOContainerBase *bcontainer = &container->bcontainer;
>+    VFIODevice *vbasedev;
>+
>+    QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) {
>+        vbasedev->cpr.reused = false;
>+    }
>+    container->be->cpr_reused = false;

It's strange to set iommufd and vfio device's reused in container's post load,
Maybe better to do it in their own post load handler?

>+
>+    return 0;
>+}
>+
> static const VMStateDescription vfio_container_vmstate = {
>     .name = "vfio-iommufd-container",
>     .version_id = 0,
>     .minimum_version_id = 0,
>+    .post_load = vfio_container_post_load,
>     .needed = cpr_needed_for_reuse,
>     .fields = (VMStateField[]) {
>         VMSTATE_END_OF_LIST()
>diff --git a/hw/vfio/device.c b/hw/vfio/device.c
>index 8e9de68..02f384e 100644
>--- a/hw/vfio/device.c
>+++ b/hw/vfio/device.c
>@@ -312,14 +312,8 @@ bool vfio_device_get_name(VFIODevice *vbasedev,
>Error **errp)
>
> void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp)
> {
>-    ERRP_GUARD();
>-    int fd = monitor_fd_param(monitor_cur(), str, errp);
>-
>-    if (fd < 0) {
>-        error_prepend(errp, "Could not parse remote object fd %s:", str);
>-        return;
>-    }
>-    vbasedev->fd = fd;
>+    vbasedev->fd = cpr_get_fd_param(vbasedev->dev->id, str, 0,
>+                                    &vbasedev->cpr.reused, errp);

Same here.

> }
>
> static VFIODeviceIOOps vfio_device_io_ops_ioctl;
>diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>index dabb948..046f601 100644
>--- a/hw/vfio/iommufd.c
>+++ b/hw/vfio/iommufd.c
>@@ -26,6 +26,7 @@
> #include "qemu/cutils.h"
> #include "qemu/chardev_open.h"
> #include "migration/blocker.h"
>+#include "migration/cpr.h"
> #include "pci.h"
> #include "vfio-iommufd.h"
> #include "vfio-helpers.h"
>@@ -530,13 +531,18 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
>
>VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD));
>
>     if (vbasedev->fd < 0) {
>-        devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp);
>+        devfd = cpr_find_fd(vbasedev->name, 0);
>+        vbasedev->cpr.reused = (devfd >= 0);
>+        if (!vbasedev->cpr.reused) {
>+            devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp);
>+        }
>         if (devfd < 0) {
>             return false;
>         }
>         vbasedev->fd = devfd;
>     } else {
>         devfd = vbasedev->fd;
>+        /* reused was set in iommufd_backend_set_fd */

Should be vfio_device_set_fd

>     }
>
>     if (!iommufd_cdev_connect_and_bind(vbasedev, errp)) {
>@@ -634,7 +640,9 @@ found_container:
>
>     vfio_device_prepare(vbasedev, bcontainer, &dev_info);
>     vfio_iommufd_cpr_register_device(vbasedev);
>-
>+    if (!vbasedev->cpr.reused) {
>+        cpr_save_fd(vbasedev->name, 0, vbasedev->fd);
>+    }
>     trace_iommufd_cdev_device_info(vbasedev->name, devfd, vbasedev-
>>num_irqs,
>                                    vbasedev->num_regions, vbasedev->flags);
>     return true;
>@@ -673,6 +681,7 @@ static void iommufd_cdev_detach(VFIODevice *vbasedev)
>
>     migrate_del_blocker(&vbasedev->cpr.id_blocker);
>     vfio_iommufd_cpr_unregister_device(vbasedev);
>+    cpr_delete_fd(vbasedev->name, 0);
>     iommufd_cdev_unbind_and_disconnect(vbasedev);
>     close(vbasedev->fd);
> }
>diff --git a/include/system/iommufd.h b/include/system/iommufd.h
>index db9ed53..5c17abd 100644
>--- a/include/system/iommufd.h
>+++ b/include/system/iommufd.h
>@@ -32,6 +32,7 @@ struct IOMMUFDBackend {
>     /*< protected >*/
>     int fd;            /* /dev/iommu file descriptor */
>     bool owned;        /* is the /dev/iommu opened internally */
>+    bool cpr_reused;   /* fd is reused after CPR */
>     uint32_t users;
>
>     /*< public >*/
>--
>1.8.3.1


Reply via email to