qemu-devel
[Top][All Lists]
Advanced

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

[RFC V1 05/12] iommufd: preserve device fd


From: Steve Sistare
Subject: [RFC V1 05/12] iommufd: preserve device fd
Date: Sat, 20 Jul 2024 12:15:30 -0700

Save the iommu and vfio device fd in CPR state when it is created, and fetch
the fd from that state after CPR.  Save the devid as the fd id.  Remember
that the fd was reused, for subsequent patches.

Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
 backends/iommufd.c       | 12 +++++++++++-
 hw/vfio/iommufd.c        | 17 ++++++++++++++++-
 include/sysemu/iommufd.h |  1 +
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/backends/iommufd.c b/backends/iommufd.c
index fc37386..4bdbad2 100644
--- a/backends/iommufd.c
+++ b/backends/iommufd.c
@@ -16,6 +16,7 @@
 #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 <sys/ioctl.h>
@@ -77,11 +78,17 @@ bool iommufd_backend_connect(IOMMUFDBackend *be, const char 
*name, Error **errp)
     int fd;
 
     if (be->owned && !be->users) {
-        fd = qemu_open_old("/dev/iommu", O_RDWR);
+        g_autofree char *iname = g_strdup_printf("%s_iommu", name);
+        fd = cpr_find_fd(iname, 0);
+        be->reused = (fd >= 0);
+        if (!be->reused) {
+            fd = qemu_open_old("/dev/iommu", O_RDWR);
+        }
         if (fd < 0) {
             error_setg_errno(errp, errno, "/dev/iommu opening failed");
             return false;
         }
+        cpr_resave_fd(iname, 0, fd);
         be->fd = fd;
     }
     be->users++;
@@ -92,6 +99,8 @@ bool iommufd_backend_connect(IOMMUFDBackend *be, const char 
*name, Error **errp)
 
 void iommufd_backend_disconnect(IOMMUFDBackend *be, const char *name)
 {
+    g_autofree char *iname = g_strdup_printf("%s_iommu", name);
+
     if (!be->users) {
         goto out;
     }
@@ -101,6 +110,7 @@ void iommufd_backend_disconnect(IOMMUFDBackend *be, const 
char *name)
         be->fd = -1;
     }
 out:
+    cpr_delete_fd(iname, 0);
     trace_iommufd_backend_disconnect(be->fd, be->users);
 }
 
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 255966a..cefc9e0 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -24,6 +24,7 @@
 #include "sysemu/reset.h"
 #include "qemu/cutils.h"
 #include "qemu/chardev_open.h"
+#include "migration/cpr.h"
 #include "pci.h"
 
 static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
@@ -84,6 +85,11 @@ static bool iommufd_cdev_connect_and_bind(VFIODevice 
*vbasedev, Error **errp)
         goto err_kvm_device_add;
     }
 
+    if (vbasedev->reused) {
+        /* Already bound, and devid was set in iommufd_cdev_attach */
+        goto skip_bind;
+    }
+
     /* Bind device to iommufd */
     bind.iommufd = iommufd->fd;
     if (ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, &bind)) {
@@ -95,6 +101,8 @@ static bool iommufd_cdev_connect_and_bind(VFIODevice 
*vbasedev, Error **errp)
     vbasedev->devid = bind.out_devid;
     trace_iommufd_cdev_connect_and_bind(bind.iommufd, vbasedev->name,
                                         vbasedev->fd, vbasedev->devid);
+
+skip_bind:
     return true;
 err_bind:
     iommufd_cdev_kvm_device_del(vbasedev);
@@ -305,13 +313,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_any(vbasedev->name, (int *)&vbasedev->devid);
+        vbasedev->reused = (devfd >= 0);
+        if (!vbasedev->reused) {
+            devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp);
+        }
         if (devfd < 0) {
             return false;
         }
         vbasedev->fd = devfd;
     } else {
         devfd = vbasedev->fd;
+        vbasedev->reused = false;
     }
 
     if (!iommufd_cdev_connect_and_bind(vbasedev, errp)) {
@@ -413,6 +426,7 @@ found_container:
     vbasedev->bcontainer = bcontainer;
     QLIST_INSERT_HEAD(&bcontainer->device_list, vbasedev, container_next);
     QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next);
+    cpr_resave_fd(vbasedev->name, vbasedev->devid, devfd);
 
     trace_iommufd_cdev_device_info(vbasedev->name, devfd, vbasedev->num_irqs,
                                    vbasedev->num_regions, vbasedev->flags);
@@ -452,6 +466,7 @@ static void iommufd_cdev_detach(VFIODevice *vbasedev)
     iommufd_cdev_container_destroy(container);
     vfio_put_address_space(space);
 
+    cpr_delete_fd(vbasedev->name, vbasedev->devid);
     iommufd_cdev_unbind_and_disconnect(vbasedev);
     close(vbasedev->fd);
 }
diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
index aa195d1..6955ebd 100644
--- a/include/sysemu/iommufd.h
+++ b/include/sysemu/iommufd.h
@@ -32,6 +32,7 @@ struct IOMMUFDBackend {
     /*< protected >*/
     int fd;            /* /dev/iommu file descriptor */
     bool owned;        /* is the /dev/iommu opened internally */
+    bool reused;       /* fd is reused after CPR */
     uint32_t users;
 
     /*< public >*/
-- 
1.8.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]