From 999a9a3fb979242c7c48dbf40fb5ebbb42faf89b Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 27 Aug 2024 11:05:30 -0700 Subject: [PATCH] gfxstream: guest: fix timeout issues This logic sequentially waits for each sync file descriptor, followed by a vkWaitForFences, but keeps track of total aggregate time spent inside the function. Previously, external fences were waited on for 3000ms somewhat arbitrarily, while the timeout was respected for non external fences. Also multiple threads were used, which is a more complex way. One can also use sync_accumulate(..) for the external fences, but that isn't done since an equivalent does not yet exist for the Kumquat layer. Proper solution would be the new virtio-gpu fence passing protocol. Reviewed-by: Aaron Ruby Acked-by: Yonggang Luo Acked-by: Adam Jackson Part-of: --- .../guest/vulkan_enc/ResourceTracker.cpp | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp b/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp index f377d5e9673..2598c2b2368 100644 --- a/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp +++ b/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp @@ -25,6 +25,7 @@ #include "goldfish_address_space.h" #include "goldfish_vk_private_defs.h" #include "util.h" +#include "util/macros.h" #include "virtgpu_gfxstream_protocol.h" #include "vulkan/vulkan_core.h" @@ -35,6 +36,7 @@ #include #include +#include #include #include #include @@ -52,7 +54,6 @@ #include #include - static inline int inline_memfd_create(const char* name, unsigned int flags) { #if defined(__ANDROID__) return syscall(SYS_memfd_create, name, flags); @@ -4915,22 +4916,31 @@ VkResult ResourceTracker::on_vkWaitForFences(void* context, VkResult, VkDevice d return enc->vkWaitForFences(device, fenceCount, pFences, waitAll, timeout, true /* do lock */); } else { - // Depending on wait any or wait all, - // schedule a wait group with waitAny/waitAll - mesa_logd("%s: scheduling ext waits\n", __func__); + auto* syncHelper = + ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper(); for (auto fd : fencesExternalWaitFds) { - mesa_logd("%s: wait on %d\n", __func__, fd); - auto* syncHelper = - ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper(); - syncHelper->wait(fd, 3000); - mesa_logd("done waiting on fd %d\n", fd); + mesa_logd("Waiting on sync fd: %d", fd); + + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + // syncHelper works in milliseconds + syncHelper->wait(fd, DIV_ROUND_UP(timeout, 1000)); + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + + uint64_t timeTaken = + std::chrono::duration_cast(end - begin).count(); + if (timeTaken >= timeout) { + return VK_TIMEOUT; + } + + timeout -= timeTaken; + mesa_logd("Done waiting on sync fd: %d", fd); } if (!fencesNonExternal.empty()) { auto hostConn = ResourceTracker::threadingCallbacks.hostConnectionGetFunc(); auto vkEncoder = ResourceTracker::threadingCallbacks.vkEncoderGetFunc(hostConn); - mesa_logd("%s: vkWaitForFences to host\n", __func__); + mesa_logd("vkWaitForFences to host"); return vkEncoder->vkWaitForFences(device, fencesNonExternal.size(), fencesNonExternal.data(), waitAll, timeout, true /* do lock */);