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
