[PATCH 3/3] drm/amdgpu: fix lock cleanup during buffer creation

Nicolai Hähnle nhaehnle at gmail.com
Tue Feb 14 10:37:44 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

Open-code the initial ttm_bo_validate call, so that we can properly
unlock the reservation lock when it fails. Also, properly destruct
the reservation object when the first part of TTM BO initialization
fails.

Actual deadlocks caused by the missing unlock should have been fixed
by "drm/ttm: never add BO that failed to validate to the LRU list",
superseding the flawed fix in commit 38fc4856ad98 ("drm/amdgpu: fix
a potential deadlock in amdgpu_bo_create_restricted()").

This change fixes remaining recursive locking errors that can be seen
with lock debugging enabled, and avoids the error of freeing a locked
mutex.

Fixes: 12a852219583 ("drm/amdgpu: improve AMDGPU_GEM_CREATE_VRAM_CLEARED handling (v2)")
Signed-off-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 32 +++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index d1ef1d0..bea845f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -399,12 +399,34 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
 		locked = ww_mutex_trylock(&bo->tbo.ttm_resv.lock);
 		WARN_ON(!locked);
 	}
-	r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type,
-			&bo->placement, page_align, !kernel, NULL,
-			acc_size, sg, resv ? resv : &bo->tbo.ttm_resv,
-			&amdgpu_ttm_bo_destroy);
-	if (unlikely(r != 0))
+	r = ttm_bo_init_top(&adev->mman.bdev, &bo->tbo, size, type,
+			    page_align, NULL,
+			    acc_size, sg, resv ? resv : &bo->tbo.ttm_resv,
+			    &amdgpu_ttm_bo_destroy);
+	if (unlikely(r != 0)) {
+		if (!resv) {
+			ww_mutex_unlock(&bo->tbo.ttm_resv.lock);
+			reservation_object_fini(&bo->tbo.ttm_resv);
+		}
+		amdgpu_ttm_bo_destroy(&bo->tbo);
+		return r;
+	}
+
+	r = ttm_bo_validate(&bo->tbo, &bo->placement, !kernel, false);
+	if (unlikely(r != 0)) {
+		struct ttm_buffer_object *tbo = &bo->tbo;
+
+		if (!resv)
+			ww_mutex_unlock(&bo->tbo.ttm_resv.lock);
+		ttm_bo_unref(&tbo);
 		return r;
+	}
+
+	if (!(bo->tbo.mem.placement & TTM_PL_FLAG_NO_EVICT)) {
+		spin_lock(&bo->tbo.glob->lru_lock);
+		ttm_bo_add_to_lru(&bo->tbo);
+		spin_unlock(&bo->tbo.glob->lru_lock);
+	}
 
 	bo->tbo.priority = ilog2(bo->tbo.num_pages);
 	if (kernel)
-- 
2.9.3



More information about the dri-devel mailing list