venus: defer roundtrip waiting to vkFreeMemory time
authorYiwei Zhang <zzyiwei@chromium.org>
Sun, 28 Nov 2021 00:04:11 +0000 (00:04 +0000)
committerMarge Bot <emma+marge@anholt.net>
Sat, 4 Dec 2021 01:48:16 +0000 (01:48 +0000)
bo allocations for the below cases are after device memory allocation:

1. direct non-external mappable memory allocation
2. pool grow
3. exportable memory allocation

For (1) and (2), the bo is for mapping, which is a pure kernel operation
to happen later. So roundtrip waiting can be deferred until free memory.

For (3), the bo is for either fd export or mapping, which are both pure
kernel operations. So roundtrip waiting can also be deferred until free
memory.

Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13874>

src/virtio/vulkan/vn_device_memory.c
src/virtio/vulkan/vn_device_memory.h

index 687a107..82f95e9 100644 (file)
@@ -61,16 +61,24 @@ vn_device_memory_pool_grow_alloc(struct vn_device *dev,
 
    result = vn_renderer_bo_create_from_device_memory(
       dev->renderer, mem->size, mem->base.id, mem_flags, 0, &mem->base_bo);
-   if (result != VK_SUCCESS)
+   if (result != VK_SUCCESS) {
+      assert(!mem->base_bo);
       goto fail;
+   }
 
-   vn_instance_roundtrip(dev->instance);
+   result =
+      vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno);
+   if (result != VK_SUCCESS)
+      goto fail;
 
+   mem->bo_roundtrip_seqno_valid = true;
    *out_mem = mem;
 
    return VK_SUCCESS;
 
 fail:
+   if (mem->base_bo)
+      vn_renderer_bo_unref(dev->renderer, mem->base_bo);
    if (mem_handle != VK_NULL_HANDLE)
       vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL);
    vn_object_base_fini(&mem->base);
@@ -100,6 +108,10 @@ vn_device_memory_pool_unref(struct vn_device *dev,
    if (!vn_renderer_bo_unref(dev->renderer, pool_mem->base_bo))
       return;
 
+   /* wait on valid bo_roundtrip_seqno before vkFreeMemory */
+   if (pool_mem->bo_roundtrip_seqno_valid)
+      vn_instance_wait_roundtrip(dev->instance, pool_mem->bo_roundtrip_seqno);
+
    vn_async_vkFreeMemory(dev->instance, vn_device_to_handle(dev),
                          vn_device_memory_to_handle(pool_mem), NULL);
    vn_object_base_fini(&pool_mem->base);
@@ -292,7 +304,15 @@ vn_device_memory_alloc(struct vn_device *dev,
       return result;
    }
 
-   vn_instance_roundtrip(dev->instance);
+   result =
+      vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno);
+   if (result != VK_SUCCESS) {
+      vn_renderer_bo_unref(dev->renderer, mem->base_bo);
+      vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL);
+      return result;
+   }
+
+   mem->bo_roundtrip_seqno_valid = true;
 
    return VK_SUCCESS;
 }
@@ -399,6 +419,10 @@ vn_FreeMemory(VkDevice device,
    } else {
       if (mem->base_bo)
          vn_renderer_bo_unref(dev->renderer, mem->base_bo);
+
+      if (mem->bo_roundtrip_seqno_valid)
+         vn_instance_wait_roundtrip(dev->instance, mem->bo_roundtrip_seqno);
+
       vn_async_vkFreeMemory(dev->instance, device, memory, NULL);
    }
 
index 04f23d1..aedd846 100644 (file)
@@ -28,6 +28,9 @@ struct vn_device_memory {
    struct vn_device_memory *base_memory;
    /* non-NULL when mappable or external */
    struct vn_renderer_bo *base_bo;
+   /* enforce kernel and ring ordering between memory export and free */
+   bool bo_roundtrip_seqno_valid;
+   uint32_t bo_roundtrip_seqno;
    VkDeviceSize base_offset;
 
    VkDeviceSize map_end;