From: Christian König Date: Tue, 7 Dec 2021 09:10:15 +0000 (+0100) Subject: drm/nouveau: wait for the exclusive fence after the shared ones v2 X-Git-Tag: v6.1~6^2^2~213 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=67f74302f45d5d862f22ced3297624e50ac352f0;p=platform%2Fkernel%2Flinux-starfive.git drm/nouveau: wait for the exclusive fence after the shared ones v2 Always waiting for the exclusive fence resulted on some performance regressions. So try to wait for the shared fences first, then the exclusive fence should always be signaled already. v2: fix incorrectly placed "(", add some comment why we do this. Signed-off-by: Christian König Tested-by: Stefan Fritsch Tested-by: Dan Moulding Acked-by: Ben Skeggs Signed-off-by: Christian König Cc: Link: https://patchwork.freedesktop.org/patch/msgid/20211209102335.18321-1-christian.koenig@amd.com --- diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 05d0b3e..0ae416a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -353,15 +353,22 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool e if (ret) return ret; - } - fobj = dma_resv_shared_list(resv); - fence = dma_resv_excl_fence(resv); + fobj = NULL; + } else { + fobj = dma_resv_shared_list(resv); + } - if (fence) { + /* Waiting for the exclusive fence first causes performance regressions + * under some circumstances. So manually wait for the shared ones first. + */ + for (i = 0; i < (fobj ? fobj->shared_count : 0) && !ret; ++i) { struct nouveau_channel *prev = NULL; bool must_wait = true; + fence = rcu_dereference_protected(fobj->shared[i], + dma_resv_held(resv)); + f = nouveau_local_fence(fence, chan->drm); if (f) { rcu_read_lock(); @@ -373,20 +380,13 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool e if (must_wait) ret = dma_fence_wait(fence, intr); - - return ret; } - if (!exclusive || !fobj) - return ret; - - for (i = 0; i < fobj->shared_count && !ret; ++i) { + fence = dma_resv_excl_fence(resv); + if (fence) { struct nouveau_channel *prev = NULL; bool must_wait = true; - fence = rcu_dereference_protected(fobj->shared[i], - dma_resv_held(resv)); - f = nouveau_local_fence(fence, chan->drm); if (f) { rcu_read_lock(); @@ -398,6 +398,8 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool e if (must_wait) ret = dma_fence_wait(fence, intr); + + return ret; } return ret;