summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_fence.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_fence.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index ab1bbfbf266e..42694b122eef 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -393,8 +393,18 @@ nouveau_fence_sync(struct nouveau_fence *fence,
return nouveau_fence_wait(fence, NULL, false, false);
}
+ /* try to take wchan's mutex, if we can't take it right away
+ * we have to fallback to software sync to prevent locking
+ * order issues
+ */
+ if (!mutex_trylock(&wchan->mutex)) {
+ free_semaphore(&sema->ref);
+ return nouveau_fence_wait(fence, NULL, false, false);
+ }
+
/* Make wchan wait until it gets signalled */
ret = emit_semaphore(wchan, NV_SW_SEMAPHORE_ACQUIRE, sema);
+ mutex_unlock(&wchan->mutex);
if (ret)
goto out;