[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
- [RFC V1 00/12] Live update: iommufd, Steve Sistare, 2024/07/20
- [RFC V1 10/12] migration/ram: old host address, Steve Sistare, 2024/07/20
- [RFC V1 07/12] iommufd: change_process kernel interface, Steve Sistare, 2024/07/20
- [RFC V1 05/12] iommufd: preserve device fd,
Steve Sistare <=
- [RFC V1 02/12] iommufd: no DMA to BARs, Steve Sistare, 2024/07/20
- [RFC V1 08/12] vfio/iommufd: register container for cpr, Steve Sistare, 2024/07/20
- [RFC V1 03/12] iommufd: pass name to connect, Steve Sistare, 2024/07/20
- [RFC V1 09/12] vfio/iommufd: rebuild device, Steve Sistare, 2024/07/20
- [RFC V1 12/12] vfio: mdev blocker, Steve Sistare, 2024/07/20
- [RFC V1 06/12] iommufd: export iommufd_cdev_get_info_iova_range, Steve Sistare, 2024/07/20
- [RFC V1 11/12] iommufd: update DMA virtual addresses, Steve Sistare, 2024/07/20
- [RFC V1 04/12] migration: cpr_find_fd_any, Steve Sistare, 2024/07/20
- [RFC V1 01/12] vfio: move cpr_exec_notifier, Steve Sistare, 2024/07/20