aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ttm
diff options
context:
space:
mode:
authorMaarten Lankhorst <m.b.lankhorst@gmail.com>2012-11-28 06:25:42 -0500
committerDave Airlie <airlied@redhat.com>2012-12-10 05:21:06 -0500
commit2b7b3ad2fb8f904ae9ba7ca71323bc11c0978d91 (patch)
treee5ae35e162bf9d2248362d34126488447a7e0ab3 /drivers/gpu/drm/ttm
parent85b144f860176ec18db927d6d9ecdfb24d9c6483 (diff)
drm/ttm: cope with reserved buffers on swap list in ttm_bo_swapout, v2
Replace the while loop with a simple for each loop, and only run the delayed destroy cleanup if we can reserve the buffer first. No race occurs, since lru lock is never dropped any more. An empty list and a list full of unreservable buffers both cause -EBUSY to be returned, which is identical to the previous situation. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/ttm')
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c44
1 files changed, 14 insertions, 30 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index ef223d581a70..9a479885bf59 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1813,41 +1813,25 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
1813 uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM); 1813 uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM);
1814 1814
1815 spin_lock(&glob->lru_lock); 1815 spin_lock(&glob->lru_lock);
1816 while (ret == -EBUSY) { 1816 list_for_each_entry(bo, &glob->swap_lru, swap) {
1817 if (unlikely(list_empty(&glob->swap_lru))) { 1817 ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
1818 spin_unlock(&glob->lru_lock); 1818 if (!ret)
1819 return -EBUSY; 1819 break;
1820 } 1820 }
1821
1822 bo = list_first_entry(&glob->swap_lru,
1823 struct ttm_buffer_object, swap);
1824 kref_get(&bo->list_kref);
1825
1826 if (!list_empty(&bo->ddestroy)) {
1827 ttm_bo_reserve_locked(bo, false, false, false, 0);
1828 ttm_bo_cleanup_refs_and_unlock(bo, false, false);
1829 1821
1830 kref_put(&bo->list_kref, ttm_bo_release_list); 1822 if (ret) {
1831 spin_lock(&glob->lru_lock); 1823 spin_unlock(&glob->lru_lock);
1832 continue; 1824 return ret;
1833 } 1825 }
1834 1826
1835 /** 1827 kref_get(&bo->list_kref);
1836 * Reserve buffer. Since we unlock while sleeping, we need
1837 * to re-check that nobody removed us from the swap-list while
1838 * we slept.
1839 */
1840 1828
1841 ret = ttm_bo_reserve_locked(bo, false, true, false, 0); 1829 if (!list_empty(&bo->ddestroy)) {
1842 if (unlikely(ret == -EBUSY)) { 1830 ret = ttm_bo_cleanup_refs_and_unlock(bo, false, false);
1843 spin_unlock(&glob->lru_lock); 1831 kref_put(&bo->list_kref, ttm_bo_release_list);
1844 ttm_bo_wait_unreserved(bo, false); 1832 return ret;
1845 kref_put(&bo->list_kref, ttm_bo_release_list);
1846 spin_lock(&glob->lru_lock);
1847 }
1848 } 1833 }
1849 1834
1850 BUG_ON(ret != 0);
1851 put_count = ttm_bo_del_from_lru(bo); 1835 put_count = ttm_bo_del_from_lru(bo);
1852 spin_unlock(&glob->lru_lock); 1836 spin_unlock(&glob->lru_lock);
1853 1837