diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 7927fe99d017..826240d4d675 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -685,19 +685,45 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, | |||
685 | struct ttm_buffer_object *bo; | 685 | struct ttm_buffer_object *bo; |
686 | int ret, put_count = 0; | 686 | int ret, put_count = 0; |
687 | 687 | ||
688 | retry: | ||
688 | spin_lock(&glob->lru_lock); | 689 | spin_lock(&glob->lru_lock); |
690 | if (list_empty(&man->lru)) { | ||
691 | spin_unlock(&glob->lru_lock); | ||
692 | return -EBUSY; | ||
693 | } | ||
694 | |||
689 | bo = list_first_entry(&man->lru, struct ttm_buffer_object, lru); | 695 | bo = list_first_entry(&man->lru, struct ttm_buffer_object, lru); |
690 | kref_get(&bo->list_kref); | 696 | kref_get(&bo->list_kref); |
691 | ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, false, 0); | 697 | |
692 | if (likely(ret == 0)) | 698 | ret = ttm_bo_reserve_locked(bo, false, true, false, 0); |
693 | put_count = ttm_bo_del_from_lru(bo); | 699 | |
700 | if (unlikely(ret == -EBUSY)) { | ||
701 | spin_unlock(&glob->lru_lock); | ||
702 | if (likely(!no_wait)) | ||
703 | ret = ttm_bo_wait_unreserved(bo, interruptible); | ||
704 | |||
705 | kref_put(&bo->list_kref, ttm_bo_release_list); | ||
706 | |||
707 | /** | ||
708 | * We *need* to retry after releasing the lru lock. | ||
709 | */ | ||
710 | |||
711 | if (unlikely(ret != 0)) | ||
712 | return ret; | ||
713 | goto retry; | ||
714 | } | ||
715 | |||
716 | put_count = ttm_bo_del_from_lru(bo); | ||
694 | spin_unlock(&glob->lru_lock); | 717 | spin_unlock(&glob->lru_lock); |
695 | if (unlikely(ret != 0)) | 718 | |
696 | return ret; | 719 | BUG_ON(ret != 0); |
720 | |||
697 | while (put_count--) | 721 | while (put_count--) |
698 | kref_put(&bo->list_kref, ttm_bo_ref_bug); | 722 | kref_put(&bo->list_kref, ttm_bo_ref_bug); |
723 | |||
699 | ret = ttm_bo_evict(bo, interruptible, no_wait); | 724 | ret = ttm_bo_evict(bo, interruptible, no_wait); |
700 | ttm_bo_unreserve(bo); | 725 | ttm_bo_unreserve(bo); |
726 | |||
701 | kref_put(&bo->list_kref, ttm_bo_release_list); | 727 | kref_put(&bo->list_kref, ttm_bo_release_list); |
702 | return ret; | 728 | return ret; |
703 | } | 729 | } |