diff options
| -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 | } |
