>-----Original Message-----
>From: Steve Sistare <steven.sist...@oracle.com>
>Subject: [PATCH V3 33/42] vfio/iommufd: define hwpt constructors
>
>Extract hwpt creation code from iommufd_cdev_autodomains_get into the
>helpers iommufd_cdev_use_hwpt and iommufd_cdev_make_hwpt.  These will
>be used by CPR in a subsequent patch.
>
>Call vfio_device_hiod_create_and_realize earlier so iommufd_cdev_make_hwpt
>can use vbasedev->hiod hw_caps, avoiding an extra call to
>iommufd_backend_get_device_info

We had made consensus to realize hiod after attachment,
it's not a hot path so an extra call is acceptable per Cedric.

>
>No functional change.
>
>Signed-off-by: Steve Sistare <steven.sist...@oracle.com>
>---
> hw/vfio/iommufd.c | 116 ++++++++++++++++++++++++++++++----------------------
>--
> 1 file changed, 65 insertions(+), 51 deletions(-)
>
>diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>index f645a62..8661947 100644
>--- a/hw/vfio/iommufd.c
>+++ b/hw/vfio/iommufd.c
>@@ -310,16 +310,70 @@ static bool
>iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp)
>     return true;
> }
>
>+static void iommufd_cdev_use_hwpt(VFIODevice *vbasedev, VFIOIOASHwpt
>*hwpt)
>+{
>+    vbasedev->hwpt = hwpt;
>+    vbasedev->iommu_dirty_tracking = iommufd_hwpt_dirty_tracking(hwpt);
>+    QLIST_INSERT_HEAD(&hwpt->device_list, vbasedev, hwpt_next);
>+}
>+
>+/*
>+ * iommufd_cdev_make_hwpt: If @alloc_id, allocate a hwpt_id, else use
>@hwpt_id.
>+ * Create and add a hwpt struct to the container's list and to the device.
>+ * Always succeeds if !@alloc_id.
>+ */
>+static bool iommufd_cdev_make_hwpt(VFIODevice *vbasedev,
>+                                   VFIOIOMMUFDContainer *container,
>+                                   uint32_t hwpt_id, bool alloc_id,
>+                                   Error **errp)
>+{
>+    VFIOIOASHwpt *hwpt;
>+    uint32_t flags = 0;
>+
>+    /*
>+     * This is quite early and VFIO Migration state isn't yet fully
>+     * initialized, thus rely only on IOMMU hardware capabilities as to
>+     * whether IOMMU dirty tracking is going to be requested. Later
>+     * vfio_migration_realize() may decide to use VF dirty tracking
>+     * instead.
>+     */
>+    g_assert(vbasedev->hiod);
>+    if (vbasedev->hiod->caps.hw_caps & IOMMU_HW_CAP_DIRTY_TRACKING) {
>+        flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
>+    }
>+
>+    if (alloc_id) {
>+        if (!iommufd_backend_alloc_hwpt(vbasedev->iommufd, vbasedev->devid,
>+                                        container->ioas_id, flags,
>+                                        IOMMU_HWPT_DATA_NONE, 0, NULL,
>+                                        &hwpt_id, errp)) {
>+            return false;
>+        }
>+
>+        if (iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp)) {
>+            iommufd_backend_free_id(container->be, hwpt_id);
>+            return false;
>+        }
>+    }
>+
>+    hwpt = g_malloc0(sizeof(*hwpt));
>+    hwpt->hwpt_id = hwpt_id;
>+    hwpt->hwpt_flags = flags;
>+    QLIST_INIT(&hwpt->device_list);
>+
>+    QLIST_INSERT_HEAD(&container->hwpt_list, hwpt, next);
>+    container->bcontainer.dirty_pages_supported |=
>+                                vbasedev->iommu_dirty_tracking;
>+    iommufd_cdev_use_hwpt(vbasedev, hwpt);
>+    return true;
>+}
>+
> static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
>                                          VFIOIOMMUFDContainer *container,
>                                          Error **errp)
> {
>     ERRP_GUARD();
>-    IOMMUFDBackend *iommufd = vbasedev->iommufd;
>-    uint32_t type, flags = 0;
>-    uint64_t hw_caps;
>     VFIOIOASHwpt *hwpt;
>-    uint32_t hwpt_id;
>     int ret;
>
>     /* Try to find a domain */
>@@ -340,54 +394,14 @@ static bool
>iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
>
>             return false;
>         } else {
>-            vbasedev->hwpt = hwpt;
>-            QLIST_INSERT_HEAD(&hwpt->device_list, vbasedev, hwpt_next);
>-            vbasedev->iommu_dirty_tracking = 
>iommufd_hwpt_dirty_tracking(hwpt);
>+            iommufd_cdev_use_hwpt(vbasedev, hwpt);
>             return true;
>         }
>     }
>-
>-    /*
>-     * This is quite early and VFIO Migration state isn't yet fully
>-     * initialized, thus rely only on IOMMU hardware capabilities as to
>-     * whether IOMMU dirty tracking is going to be requested. Later
>-     * vfio_migration_realize() may decide to use VF dirty tracking
>-     * instead.
>-     */
>-    if (!iommufd_backend_get_device_info(vbasedev->iommufd, vbasedev->devid,
>-                                         &type, NULL, 0, &hw_caps, errp)) {
>-        return false;
>-    }
>-
>-    if (hw_caps & IOMMU_HW_CAP_DIRTY_TRACKING) {
>-        flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
>-    }
>-
>-    if (!iommufd_backend_alloc_hwpt(iommufd, vbasedev->devid,
>-                                    container->ioas_id, flags,
>-                                    IOMMU_HWPT_DATA_NONE, 0, NULL,
>-                                    &hwpt_id, errp)) {
>-        return false;
>-    }
>-
>-    hwpt = g_malloc0(sizeof(*hwpt));
>-    hwpt->hwpt_id = hwpt_id;
>-    hwpt->hwpt_flags = flags;
>-    QLIST_INIT(&hwpt->device_list);
>-
>-    ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt->hwpt_id, errp);
>-    if (ret) {
>-        iommufd_backend_free_id(container->be, hwpt->hwpt_id);
>-        g_free(hwpt);
>+    if (!iommufd_cdev_make_hwpt(vbasedev, container, 0, true, errp)) {
>         return false;
>     }
>
>-    vbasedev->hwpt = hwpt;
>-    vbasedev->iommu_dirty_tracking = iommufd_hwpt_dirty_tracking(hwpt);
>-    QLIST_INSERT_HEAD(&hwpt->device_list, vbasedev, hwpt_next);
>-    QLIST_INSERT_HEAD(&container->hwpt_list, hwpt, next);
>-    container->bcontainer.dirty_pages_supported |=
>-                                vbasedev->iommu_dirty_tracking;
>     if (container->bcontainer.dirty_pages_supported &&
>         !vbasedev->iommu_dirty_tracking) {
>         warn_report("IOMMU instance for device %s doesn't support dirty 
> tracking",
>@@ -530,6 +544,11 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
>
>     space = vfio_address_space_get(as);
>
>+    if (!vfio_device_hiod_create_and_realize(vbasedev,
>+            TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO, errp)) {
>+        goto err_alloc_ioas;
>+    }
>+
>     /* try to attach to an existing container in this space */
>     QLIST_FOREACH(bcontainer, &space->containers, next) {
>         container = container_of(bcontainer, VFIOIOMMUFDContainer, 
> bcontainer);
>@@ -604,11 +623,6 @@ found_container:
>         goto err_listener_register;
>     }
>
>-    if (!vfio_device_hiod_create_and_realize(vbasedev,
>-                     TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO, errp)) {
>-        goto err_listener_register;
>-    }
>-
>     /*
>      * TODO: examine RAM_BLOCK_DISCARD stuff, should we do group level
>      * for discarding incompatibility check as well?
>--
>1.8.3.1


Reply via email to