[PATCH 1/3] drm/ttm: Clear the buffer object bulk move at individualize time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Clearing the buffer object bulk move is closely tied to individualizing
the resv, since that is when we effectively detach the bo from a vm.

Clearing the bulk move also requires the bo resv, which we have readily
locked at individualizing time without clobbering the much wider vm
lock.

So Clear the buffer object bulk_move at individualizing time, and update
the code comments.

Signed-off-by: Thomas Hellström <thomas.hellstrom@xxxxxxxxxxxxxxx>
---
 drivers/gpu/drm/ttm/ttm_bo.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index bd5dae4d1624..57cc9f845adc 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -193,20 +193,33 @@ static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo)
 	BUG_ON(!dma_resv_trylock(&bo->base._resv));
 
 	r = dma_resv_copy_fences(&bo->base._resv, bo->base.resv);
-	dma_resv_unlock(&bo->base._resv);
-	if (r)
-		return r;
 
-	if (bo->type != ttm_bo_type_sg) {
-		/* This works because the BO is about to be destroyed and nobody
-		 * reference it any more. The only tricky case is the trylock on
-		 * the resv object while holding the lru_lock.
+	if (!r && bo->type != ttm_bo_type_sg) {
+		/*
+		 * The TTM bo refcount is now zero and hence nobody will
+		 * therefore try to lock the bo at this point: the LRU
+		 * list lookups will trylock even if the refcount is zero,
+		 * but will only do that under the LRU lock and will
+		 * then immediately back off under the same LRU lock when it
+		 * sees the zero refcount.
 		 */
 		spin_lock(&bo->bdev->lru_lock);
 		bo->base.resv = &bo->base._resv;
+
+		/* Since bulk move is closely tied with the shared resv,
+		 * clear it when we have now individualized, if that was not
+		 * done by the driver already.
+		 */
+		if (bo->bulk_move) {
+			if (bo->resource)
+				ttm_resource_del_bulk_move(bo->resource, bo);
+			bo->bulk_move = NULL;
+		}
 		spin_unlock(&bo->bdev->lru_lock);
 	}
 
+	dma_resv_unlock(&bo->base._resv);
+
 	return r;
 }
 
@@ -324,7 +337,6 @@ static void ttm_bo_release(struct kref *kref)
 	int ret;
 
 	WARN_ON_ONCE(bo->pin_count);
-	WARN_ON_ONCE(bo->bulk_move);
 
 	if (!bo->deleted) {
 		ret = ttm_bo_individualize_resv(bo);
@@ -337,6 +349,8 @@ static void ttm_bo_release(struct kref *kref)
 					      30 * HZ);
 		}
 
+		WARN_ON_ONCE(bo->bulk_move);
+
 		if (bo->bdev->funcs->release_notify)
 			bo->bdev->funcs->release_notify(bo);
 
-- 
2.39.2




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux