[PATCH] drm/ttm: Fix busy codepaths of the "Fix two race conditions" commit.
Thomas Hellstrom
thellstrom at vmware.com
Fri Oct 1 03:15:44 PDT 2010
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 at 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;
--
1.6.2.5
More information about the dri-devel
mailing list