From 88b64d14d8392f481e17660f7612d1ac87a4fe15 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Sun, 17 Mar 2024 23:24:31 -0700 Subject: [PATCH] venus: add enum vn_relax_reason MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Better distinguish different client waiting and prepare for applying different waiting profile for different reasons. Default case is avoided in reason string mapping so that below can be hit upon compilation: - error: enumeration value ‘XXX’ not handled in switch [-Werror=switch] Signed-off-by: Yiwei Zhang Part-of: --- src/virtio/vulkan/meson.build | 4 +++- src/virtio/vulkan/vn_common.c | 24 +++++++++++++++++++++--- src/virtio/vulkan/vn_common.h | 12 ++++++++++-- src/virtio/vulkan/vn_queue.c | 8 ++++---- src/virtio/vulkan/vn_ring.c | 4 ++-- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/virtio/vulkan/meson.build b/src/virtio/vulkan/meson.build index 4933c69e19e..c6c376b48fb 100644 --- a/src/virtio/vulkan/meson.build +++ b/src/virtio/vulkan/meson.build @@ -84,7 +84,9 @@ vn_deps = [ vn_flags = [ no_override_init_args, -] +] + cc.get_supported_arguments([ + '-Werror=switch', +]) vn_libs = [] diff --git a/src/virtio/vulkan/vn_common.c b/src/virtio/vulkan/vn_common.c index 5d32e1a1958..33da57e0641 100644 --- a/src/virtio/vulkan/vn_common.c +++ b/src/virtio/vulkan/vn_common.c @@ -171,8 +171,25 @@ vn_relax_fini(struct vn_relax_state *state) vn_watchdog_release(&state->instance->ring.watchdog); } +static inline const char * +vn_relax_reason_string(enum vn_relax_reason reason) +{ + /* deliberately avoid default case for -Wswitch to catch upon compile */ + switch (reason) { + case VN_RELAX_REASON_RING_SEQNO: + return "ring seqno"; + case VN_RELAX_REASON_RING_SPACE: + return "ring space"; + case VN_RELAX_REASON_FENCE: + return "fence"; + case VN_RELAX_REASON_SEMAPHORE: + return "semaphore"; + } + return ""; +} + struct vn_relax_state -vn_relax_init(struct vn_instance *instance, const char *reason) +vn_relax_init(struct vn_instance *instance, enum vn_relax_reason reason) { struct vn_ring *ring = instance->ring.ring; struct vn_watchdog *watchdog = &instance->ring.watchdog; @@ -183,6 +200,7 @@ vn_relax_init(struct vn_instance *instance, const char *reason) .instance = instance, .iter = 0, .reason = reason, + .reason_str = vn_relax_reason_string(reason), }; } @@ -190,7 +208,7 @@ void vn_relax(struct vn_relax_state *state) { uint32_t *iter = &state->iter; - const char *reason = state->reason; + const char *reason_str = state->reason_str; /* Yield for the first 2^busy_wait_order times and then sleep for * base_sleep_us microseconds for the same number of times. After that, @@ -213,7 +231,7 @@ vn_relax(struct vn_relax_state *state) */ if (unlikely(*iter % (1 << warn_order) == 0)) { struct vn_instance *instance = state->instance; - vn_log(instance, "stuck in %s wait with iter at %d", reason, *iter); + vn_log(instance, "stuck in %s wait with iter at %d", reason_str, *iter); struct vn_ring *ring = instance->ring.ring; const uint32_t status = vn_ring_load_status(ring); diff --git a/src/virtio/vulkan/vn_common.h b/src/virtio/vulkan/vn_common.h index ed187dea15d..5d5e80b04d9 100644 --- a/src/virtio/vulkan/vn_common.h +++ b/src/virtio/vulkan/vn_common.h @@ -207,10 +207,18 @@ struct vn_watchdog { atomic_bool alive; }; +enum vn_relax_reason { + VN_RELAX_REASON_RING_SEQNO, + VN_RELAX_REASON_RING_SPACE, + VN_RELAX_REASON_FENCE, + VN_RELAX_REASON_SEMAPHORE, +}; + struct vn_relax_state { struct vn_instance *instance; uint32_t iter; - const char *reason; + enum vn_relax_reason reason; + const char *reason_str; }; /* TLS ring @@ -363,7 +371,7 @@ vn_watchdog_fini(struct vn_watchdog *watchdog) } struct vn_relax_state -vn_relax_init(struct vn_instance *instance, const char *reason); +vn_relax_init(struct vn_instance *instance, enum vn_relax_reason reason); void vn_relax(struct vn_relax_state *state); diff --git a/src/virtio/vulkan/vn_queue.c b/src/virtio/vulkan/vn_queue.c index 7a74743ac23..4674087e192 100644 --- a/src/virtio/vulkan/vn_queue.c +++ b/src/virtio/vulkan/vn_queue.c @@ -1722,7 +1722,7 @@ vn_WaitForFences(VkDevice device, memcpy(fences, pFences, sizeof(*fences) * fenceCount); struct vn_relax_state relax_state = - vn_relax_init(dev->instance, "client"); + vn_relax_init(dev->instance, VN_RELAX_REASON_FENCE); while (result == VK_NOT_READY) { result = vn_remove_signaled_fences(device, fences, &fenceCount); result = @@ -1734,7 +1734,7 @@ vn_WaitForFences(VkDevice device, vk_free(alloc, fences); } else { struct vn_relax_state relax_state = - vn_relax_init(dev->instance, "client"); + vn_relax_init(dev->instance, VN_RELAX_REASON_FENCE); while (result == VK_NOT_READY) { result = vn_find_first_signaled_fence(device, pFences, fenceCount); result = @@ -2247,7 +2247,7 @@ vn_WaitSemaphores(VkDevice device, memcpy(values, pWaitInfo->pValues, sizeof(*values) * semaphore_count); struct vn_relax_state relax_state = - vn_relax_init(dev->instance, "client"); + vn_relax_init(dev->instance, VN_RELAX_REASON_SEMAPHORE); while (result == VK_NOT_READY) { result = vn_remove_signaled_semaphores(device, semaphores, values, &semaphore_count); @@ -2260,7 +2260,7 @@ vn_WaitSemaphores(VkDevice device, vk_free(alloc, semaphores); } else { struct vn_relax_state relax_state = - vn_relax_init(dev->instance, "client"); + vn_relax_init(dev->instance, VN_RELAX_REASON_SEMAPHORE); while (result == VK_NOT_READY) { result = vn_find_first_signaled_semaphore( device, pWaitInfo->pSemaphores, pWaitInfo->pValues, diff --git a/src/virtio/vulkan/vn_ring.c b/src/virtio/vulkan/vn_ring.c index 6e97480f252..fd209dd94b5 100644 --- a/src/virtio/vulkan/vn_ring.c +++ b/src/virtio/vulkan/vn_ring.c @@ -176,7 +176,7 @@ vn_ring_wait_seqno(struct vn_ring *ring, uint32_t seqno) * repeatedly anyway. Let's just poll here. */ struct vn_relax_state relax_state = - vn_relax_init(ring->instance, "ring seqno"); + vn_relax_init(ring->instance, VN_RELAX_REASON_RING_SEQNO); do { if (vn_ring_get_seqno_status(ring, seqno)) { vn_relax_fini(&relax_state); @@ -223,7 +223,7 @@ vn_ring_wait_space(struct vn_ring *ring, uint32_t size) /* see the reasoning in vn_ring_wait_seqno */ struct vn_relax_state relax_state = - vn_relax_init(ring->instance, "ring space"); + vn_relax_init(ring->instance, VN_RELAX_REASON_RING_SPACE); do { vn_relax(&relax_state); if (vn_ring_has_space(ring, size, &head)) {