The above mentioned commit didn't queue the buffer on the delayed destroy list under some rare circumstances. It also didn't completely honor the remove_all parameter.
Signed-off-by: Thomas Hellstrom thellstrom@vmware.com --- drivers/gpu/drm/ttm/ttm_bo.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index b98cb2c..db809e0 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -493,6 +493,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) int ret;
spin_lock(&bo->lock); +retry: (void) ttm_bo_wait(bo, false, false, !remove_all);
if (!bo->sync_obj) { @@ -501,15 +502,16 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) spin_unlock(&bo->lock);
spin_lock(&glob->lru_lock); - ret = ttm_bo_reserve_locked(bo, false, true, false, 0); + ret = ttm_bo_reserve_locked(bo, false, !remove_all, false, 0);
/** * Someone else has the object reserved. Bail and retry. */
- if (unlikely(ret != 0)) { + if (unlikely(ret == -EBUSY)) { spin_unlock(&glob->lru_lock); - return 0; + spin_lock(&bo->lock); + goto requeue; }
/** @@ -524,6 +526,11 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) atomic_set(&bo->reserved, 0); wake_up_all(&bo->event_queue); spin_unlock(&glob->lru_lock); + spin_lock(&bo->lock); + if (remove_all) + goto retry; + else + goto requeue; }
put_count = ttm_bo_del_from_lru(bo); @@ -540,7 +547,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
return 0; } - +requeue: spin_lock(&glob->lru_lock); if (list_empty(&bo->ddestroy)) { void *sync_obj = bo->sync_obj;