venus: add enum vn_relax_reason

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 <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28287>
This commit is contained in:
Yiwei Zhang 2024-03-17 23:24:31 -07:00 committed by Marge Bot
parent d05eb97408
commit 88b64d14d8
5 changed files with 40 additions and 12 deletions

View file

@ -84,7 +84,9 @@ vn_deps = [
vn_flags = [
no_override_init_args,
]
] + cc.get_supported_arguments([
'-Werror=switch',
])
vn_libs = []

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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)) {