From 34630fe081b14623adb94cca403619788e18826b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Jun 2020 15:58:33 -0700 Subject: [PATCH] turnip: Properly return VK_DEVICE_LOST on queuesubmit failures. The device lost support closely matches the anv code for the same. Part-of: --- src/freedreno/vulkan/tu_device.c | 47 +++++++++++++++++++++++++------ src/freedreno/vulkan/tu_fence.c | 3 ++ src/freedreno/vulkan/tu_private.h | 14 +++++++++ src/freedreno/vulkan/tu_query.c | 3 ++ 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index dd046f39eef..57905740eef 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -1216,6 +1216,7 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice, device->_loader_data.loaderMagic = ICD_LOADER_MAGIC; device->instance = physical_device->instance; device->physical_device = physical_device; + device->_lost = false; if (pAllocator) device->alloc = *pAllocator; @@ -1365,6 +1366,29 @@ tu_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator) vk_free(&device->alloc, device); } +VkResult +_tu_device_set_lost(struct tu_device *device, + const char *file, int line, + const char *msg, ...) +{ + /* Set the flag indicating that waits should return in finite time even + * after device loss. + */ + p_atomic_inc(&device->_lost); + + /* TODO: Report the log message through VkDebugReportCallbackEXT instead */ + fprintf(stderr, "%s:%d: ", file, line); + va_list ap; + va_start(ap, msg); + vfprintf(stderr, msg, ap); + va_end(ap); + + if (env_var_as_boolean("TU_ABORT_ON_DEVICE_LOSS", false)) + abort(); + + return VK_ERROR_DEVICE_LOST; +} + VkResult tu_get_scratch_bo(struct tu_device *dev, uint64_t size, struct tu_bo **bo) { @@ -1547,18 +1571,17 @@ tu_QueueSubmit(VkQueue _queue, pSubmits[i].waitSemaphoreCount, false, &in_syncobjs, &nr_in_syncobjs); if (result != VK_SUCCESS) { - /* TODO: emit VK_ERROR_DEVICE_LOST */ - fprintf(stderr, "failed to allocate space for semaphore submission\n"); - abort(); + return tu_device_set_lost(queue->device, + "failed to allocate space for semaphore submission\n"); } result = tu_get_semaphore_syncobjs(pSubmits[i].pSignalSemaphores, pSubmits[i].signalSemaphoreCount, false, &out_syncobjs, &nr_out_syncobjs); if (result != VK_SUCCESS) { - /* TODO: emit VK_ERROR_DEVICE_LOST */ - fprintf(stderr, "failed to allocate space for semaphore submission\n"); - abort(); + free(in_syncobjs); + return tu_device_set_lost(queue->device, + "failed to allocate space for semaphore submission\n"); } uint32_t entry_count = 0; @@ -1617,8 +1640,10 @@ tu_QueueSubmit(VkQueue _queue, DRM_MSM_GEM_SUBMIT, &req, sizeof(req)); if (ret) { - fprintf(stderr, "submit failed: %s\n", strerror(errno)); - abort(); + free(in_syncobjs); + free(out_syncobjs); + return tu_device_set_lost(queue->device, "submit failed: %s\n", + strerror(errno)); } tu_bo_list_destroy(&bo_list); @@ -1648,6 +1673,9 @@ tu_QueueWaitIdle(VkQueue _queue) { TU_FROM_HANDLE(tu_queue, queue, _queue); + if (tu_device_is_lost(queue->device)) + return VK_ERROR_DEVICE_LOST; + tu_fence_wait_idle(&queue->submit_fence); return VK_SUCCESS; @@ -1658,6 +1686,9 @@ tu_DeviceWaitIdle(VkDevice _device) { TU_FROM_HANDLE(tu_device, device, _device); + if (tu_device_is_lost(device)) + return VK_ERROR_DEVICE_LOST; + for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) { for (unsigned q = 0; q < device->queue_count[i]; q++) { tu_QueueWaitIdle(tu_queue_to_handle(&device->queues[i][q])); diff --git a/src/freedreno/vulkan/tu_fence.c b/src/freedreno/vulkan/tu_fence.c index 62094c91092..f3de4ee35f2 100644 --- a/src/freedreno/vulkan/tu_fence.c +++ b/src/freedreno/vulkan/tu_fence.c @@ -336,6 +336,9 @@ tu_WaitForFences(VkDevice _device, { TU_FROM_HANDLE(tu_device, device, _device); + if (tu_device_is_lost(device)) + return VK_ERROR_DEVICE_LOST; + /* add a simpler path for when fenceCount == 1? */ struct pollfd stack_fds[8]; diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index a70bb3b7dce..0d59c3c0659 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -47,6 +47,7 @@ #include "main/macros.h" #include "util/list.h" #include "util/macros.h" +#include "util/u_atomic.h" #include "vk_alloc.h" #include "vk_debug_report.h" #include "wsi_common.h" @@ -350,6 +351,7 @@ struct tu_device int queue_count[TU_MAX_QUEUE_FAMILIES]; struct tu_physical_device *physical_device; + int _lost; struct ir3_compiler *compiler; @@ -377,6 +379,18 @@ struct tu_device struct tu_device_extension_table enabled_extensions; }; +VkResult _tu_device_set_lost(struct tu_device *device, + const char *file, int line, + const char *msg, ...) PRINTFLIKE(4, 5); +#define tu_device_set_lost(dev, ...) \ + _tu_device_set_lost(dev, __FILE__, __LINE__, __VA_ARGS__) + +static inline bool +tu_device_is_lost(struct tu_device *device) +{ + return unlikely(p_atomic_read(&device->_lost)); +} + VkResult tu_bo_init_new(struct tu_device *dev, struct tu_bo *bo, uint64_t size); VkResult diff --git a/src/freedreno/vulkan/tu_query.c b/src/freedreno/vulkan/tu_query.c index 6a106a40614..143f144d138 100644 --- a/src/freedreno/vulkan/tu_query.c +++ b/src/freedreno/vulkan/tu_query.c @@ -311,6 +311,9 @@ tu_GetQueryPoolResults(VkDevice _device, TU_FROM_HANDLE(tu_query_pool, pool, queryPool); assert(firstQuery + queryCount <= pool->size); + if (tu_device_is_lost(device)) + return VK_ERROR_DEVICE_LOST; + switch (pool->type) { case VK_QUERY_TYPE_OCCLUSION: case VK_QUERY_TYPE_TIMESTAMP: -- 2.30.2