drm/ttm: Delayed delete fixes.
authorThomas Hellstrom <thellstrom@vmware.com>
Wed, 2 Dec 2009 17:33:45 +0000 (18:33 +0100)
committerDave Airlie <airlied@redhat.com>
Wed, 16 Dec 2009 05:34:36 +0000 (15:34 +1000)
1) Remove from lru before reserving so we avoid competing with
evicting processes.
2) Avoid calling kref_put() on bo::list_kref while spinlocked.
3) Additional refcounting bug-checking.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/ttm/ttm_bo.c

index 4cd4007e68faec3eb83f4b9db35cff04b579c6dd..7927fe99d01705ed130413fcb926d884ccd9c46f 100644 (file)
@@ -465,6 +465,8 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
                spin_unlock(&bo->lock);
 
                spin_lock(&glob->lru_lock);
+               put_count = ttm_bo_del_from_lru(bo);
+
                ret = ttm_bo_reserve_locked(bo, false, false, false, 0);
                BUG_ON(ret);
                if (bo->ttm)
@@ -472,20 +474,19 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
 
                if (!list_empty(&bo->ddestroy)) {
                        list_del_init(&bo->ddestroy);
-                       kref_put(&bo->list_kref, ttm_bo_ref_bug);
+                       ++put_count;
                }
                if (bo->mem.mm_node) {
                        bo->mem.mm_node->private = NULL;
                        drm_mm_put_block(bo->mem.mm_node);
                        bo->mem.mm_node = NULL;
                }
-               put_count = ttm_bo_del_from_lru(bo);
                spin_unlock(&glob->lru_lock);
 
                atomic_set(&bo->reserved, 0);
 
                while (put_count--)
-                       kref_put(&bo->list_kref, ttm_bo_release_list);
+                       kref_put(&bo->list_kref, ttm_bo_ref_bug);
 
                return 0;
        }