Instead of trying to grab a BO reference.

Also lock the dma_resv object, that TT unpopulate is done without
holding the lock looks extremely suspicious.

Only compile tested!

Signed-off-by: Christian König <[email protected]>
---
 drivers/gpu/drm/ttm/ttm_device.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index e4188e2ee7ab1..be6fc42772f9d 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -293,19 +293,29 @@ static void ttm_device_clear_lru_dma_mappings(struct 
ttm_device *bdev,
 
        spin_lock(&bdev->lru_lock);
        while ((res = ttm_lru_first_res_or_null(list))) {
-               struct ttm_buffer_object *bo = res->bo;
+               struct dma_resv *resv;
 
                /* Take ref against racing releases once lru_lock is unlocked */
-               if (!ttm_bo_get_unless_zero(bo))
-                       continue;
+               resv = dma_resv_get(res->bo->base.resv);
+               spin_unlock(&bdev->lru_lock);
+
+               dma_resv_lock(resv, NULL);
 
-               list_del_init(&bo->resource->lru.link);
+               /* Double check that res and bo is still valid */
+               spin_lock(&bdev->lru_lock);
+               if (res != ttm_lru_first_res_or_null(list)) {
+                       dma_resv_unlock(resv);
+                       dma_resv_put(resv);
+                       continue;
+               }
+               list_del_init(&res->lru.link);
                spin_unlock(&bdev->lru_lock);
 
-               if (bo->ttm)
-                       ttm_tt_unpopulate(bo->bdev, bo->ttm);
+               if (res->bo->ttm)
+                       ttm_tt_unpopulate(res->bo->bdev, res->bo->ttm);
 
-               ttm_bo_put(bo);
+               dma_resv_unlock(resv);
+               dma_resv_put(resv);
                spin_lock(&bdev->lru_lock);
        }
        spin_unlock(&bdev->lru_lock);
-- 
2.43.0

Reply via email to