From 86b3a4e6aa99fb017bd9b852576440aeaa2e01a4 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Sun, 28 Nov 2021 00:04:11 +0000 Subject: [PATCH] venus: defer roundtrip waiting to vkFreeMemory time 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 Reviewed-by: Chia-I Wu Part-of: --- src/virtio/vulkan/vn_device_memory.c | 30 +++++++++++++++++++++++++--- src/virtio/vulkan/vn_device_memory.h | 3 +++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/virtio/vulkan/vn_device_memory.c b/src/virtio/vulkan/vn_device_memory.c index 687a1071171..82f95e9bebc 100644 --- a/src/virtio/vulkan/vn_device_memory.c +++ b/src/virtio/vulkan/vn_device_memory.c @@ -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) { + assert(!mem->base_bo); + goto fail; + } + + result = + vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno); if (result != VK_SUCCESS) goto fail; - vn_instance_roundtrip(dev->instance); - + 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); } diff --git a/src/virtio/vulkan/vn_device_memory.h b/src/virtio/vulkan/vn_device_memory.h index 04f23d10541..aedd8465e68 100644 --- a/src/virtio/vulkan/vn_device_memory.h +++ b/src/virtio/vulkan/vn_device_memory.h @@ -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;