From 23c45e8ed203f933753fb66a6290c4ff853eb7bb Mon Sep 17 00:00:00 2001
From: Francisco Jerez <currojerez@riseup.net>
Date: Thu, 28 Oct 2010 23:10:29 +0200
Subject: [PATCH] drm/nouveau: Fix sleep while atomic in nouveau_bo_fence().

Reported-by: Pekka Paalanen <pq@iki.fi>
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/nouveau_bo.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 8d5dd980240d..f4ee43db00aa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -942,13 +942,17 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
 void
 nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence)
 {
-	spin_lock(&nvbo->bo.bdev->fence_lock);
-	__nouveau_fence_unref(&nvbo->bo.sync_obj);
+	struct nouveau_fence *old_fence;
 
 	if (likely(fence))
-		nvbo->bo.sync_obj = nouveau_fence_ref(fence);
+		nouveau_fence_ref(fence);
 
+	spin_lock(&nvbo->bo.bdev->fence_lock);
+	old_fence = nvbo->bo.sync_obj;
+	nvbo->bo.sync_obj = fence;
 	spin_unlock(&nvbo->bo.bdev->fence_lock);
+
+	nouveau_fence_unref(&old_fence);
 }
 
 struct ttm_bo_driver nouveau_bo_driver = {