Module: Mesa Branch: main Commit: 37c6c5c624b6d00443e7de1a43487b00eb30ff9f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=37c6c5c624b6d00443e7de1a43487b00eb30ff9f
Author: Karol Herbst <[email protected]> Date: Wed Apr 26 22:06:44 2023 +0200 nvc0: do not randomly emit fences. We track fences in a global list and have a per context "current" fence which we randomly attach things to. If we take such a fence and emit it without also creating a new fence for future tasks we can get out of sync leading to random failures. Some of our queries could trigger such cases and even though this issues appears to be triggered by the MT rework, I'm convinced that this was only made more visible by those fixes and we had this bug lurking for quite a while. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7429 Fixes: df0a4d02f26 ("nvc0: make state handling race free") Signed-off-by: Karol Herbst <[email protected]> Acked-by: M Henning <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22722> --- src/gallium/drivers/nouveau/nouveau_fence.c | 5 +++-- src/gallium/drivers/nouveau/nouveau_fence.h | 3 +-- src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c index 365169943e5..9fad60c4f36 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.c +++ b/src/gallium/drivers/nouveau/nouveau_fence.c @@ -374,10 +374,11 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debu } void -nouveau_fence_emit(struct nouveau_fence *fence) +nouveau_fence_next_if_current(struct nouveau_context *nv, struct nouveau_fence *fence) { simple_mtx_lock(&fence->screen->fence.lock); - _nouveau_fence_emit(fence); + if (nv->fence == fence) + _nouveau_fence_next(nv); simple_mtx_unlock(&fence->screen->fence.lock); } diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h index 444598b3eb1..384084b6d14 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.h +++ b/src/gallium/drivers/nouveau/nouveau_fence.h @@ -58,12 +58,11 @@ void _nouveau_fence_update(struct nouveau_screen *, bool flushed); void _nouveau_fence_next(struct nouveau_context *); void _nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); -void nouveau_fence_emit(struct nouveau_fence *); bool nouveau_fence_new(struct nouveau_context *, struct nouveau_fence **); void nouveau_fence_cleanup(struct nouveau_context *); bool nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *); void nouveau_fence_update(struct nouveau_screen *, bool flushed); -void nouveau_fence_next(struct nouveau_context *); +void nouveau_fence_next_if_current(struct nouveau_context *, struct nouveau_fence *); bool nouveau_fence_wait(struct nouveau_fence *, struct util_debug_callback *); bool nouveau_fence_signalled(struct nouveau_fence *); void nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c index e4c36a8ee96..c727c9d0f48 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c @@ -421,7 +421,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0, * of the following logic more complicated. */ if (hq->is64bit) - nouveau_fence_emit(hq->fence); + nouveau_fence_next_if_current(&nvc0->base, hq->fence); /* We either need to compute a 32- or 64-bit difference between 2 values, * and then store the result as either a 32- or 64-bit value. As such let's @@ -643,7 +643,7 @@ nvc0_hw_query_fifo_wait(struct nvc0_context *nvc0, struct nvc0_query *q) /* ensure the query's fence has been emitted */ if (hq->is64bit) - nouveau_fence_emit(hq->fence); + nouveau_fence_next_if_current(&nvc0->base, hq->fence); PUSH_SPACE(push, 5); PUSH_REF1 (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
