aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2017-11-08 09:55:44 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-12-06 12:47:48 -0500
commit6ba435812e0d85b016670ba7324d1bb1369d8428 (patch)
tree651813f7084a06df446bb5a8c3f410b976101594 /drivers/gpu/drm
parent56f3df448c9458ffd4c2ae62c09afc99f7ab277d (diff)
drm/ttm: optimize ttm_mem_evict_first v5
Deleted BOs with the same reservation object can be reaped even if they can't be reserved. v2: rebase and we still need to remove/add the BO from/to the LRU. v3: fix remove/add one more time, cleanup the logic a bit v4: we should still check if the eviction is valuable v5: add comment suggested by Michel Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-and-Tested-by: Michel Dänzer <michel.daenzer@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 3aa63c4679f0..07d9c6e5b6ca 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -734,47 +734,57 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
734EXPORT_SYMBOL(ttm_bo_eviction_valuable); 734EXPORT_SYMBOL(ttm_bo_eviction_valuable);
735 735
736static int ttm_mem_evict_first(struct ttm_bo_device *bdev, 736static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
737 uint32_t mem_type, 737 struct reservation_object *resv,
738 const struct ttm_place *place, 738 uint32_t mem_type,
739 bool interruptible, 739 const struct ttm_place *place,
740 bool no_wait_gpu) 740 bool interruptible,
741 bool no_wait_gpu)
741{ 742{
742 struct ttm_bo_global *glob = bdev->glob; 743 struct ttm_bo_global *glob = bdev->glob;
743 struct ttm_mem_type_manager *man = &bdev->man[mem_type]; 744 struct ttm_mem_type_manager *man = &bdev->man[mem_type];
744 struct ttm_buffer_object *bo; 745 struct ttm_buffer_object *bo = NULL;
745 int ret = -EBUSY; 746 bool locked = false;
746 unsigned i; 747 unsigned i;
748 int ret;
747 749
748 spin_lock(&glob->lru_lock); 750 spin_lock(&glob->lru_lock);
749 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { 751 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
750 list_for_each_entry(bo, &man->lru[i], lru) { 752 list_for_each_entry(bo, &man->lru[i], lru) {
751 ret = reservation_object_trylock(bo->resv) ? 0 : -EBUSY; 753 if (bo->resv == resv) {
752 if (ret) 754 if (list_empty(&bo->ddestroy))
753 continue; 755 continue;
756 } else {
757 locked = reservation_object_trylock(bo->resv);
758 if (!locked)
759 continue;
760 }
754 761
755 if (place && !bdev->driver->eviction_valuable(bo, 762 if (place && !bdev->driver->eviction_valuable(bo,
756 place)) { 763 place)) {
757 reservation_object_unlock(bo->resv); 764 if (locked)
758 ret = -EBUSY; 765 reservation_object_unlock(bo->resv);
759 continue; 766 continue;
760 } 767 }
761
762 break; 768 break;
763 } 769 }
764 770
765 if (!ret) 771 /* If the inner loop terminated early, we have our candidate */
772 if (&bo->lru != &man->lru[i])
766 break; 773 break;
774
775 bo = NULL;
767 } 776 }
768 777
769 if (ret) { 778 if (!bo) {
770 spin_unlock(&glob->lru_lock); 779 spin_unlock(&glob->lru_lock);
771 return ret; 780 return -EBUSY;
772 } 781 }
773 782
774 kref_get(&bo->list_kref); 783 kref_get(&bo->list_kref);
775 784
776 if (!list_empty(&bo->ddestroy)) { 785 if (!list_empty(&bo->ddestroy)) {
777 ret = ttm_bo_cleanup_refs(bo, interruptible, no_wait_gpu, true); 786 ret = ttm_bo_cleanup_refs(bo, interruptible, no_wait_gpu,
787 locked);
778 kref_put(&bo->list_kref, ttm_bo_release_list); 788 kref_put(&bo->list_kref, ttm_bo_release_list);
779 return ret; 789 return ret;
780 } 790 }
@@ -782,10 +792,11 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
782 ttm_bo_del_from_lru(bo); 792 ttm_bo_del_from_lru(bo);
783 spin_unlock(&glob->lru_lock); 793 spin_unlock(&glob->lru_lock);
784 794
785 BUG_ON(ret != 0);
786
787 ret = ttm_bo_evict(bo, interruptible, no_wait_gpu); 795 ret = ttm_bo_evict(bo, interruptible, no_wait_gpu);
788 ttm_bo_unreserve(bo); 796 if (locked)
797 ttm_bo_unreserve(bo);
798 else
799 ttm_bo_add_to_lru(bo);
789 800
790 kref_put(&bo->list_kref, ttm_bo_release_list); 801 kref_put(&bo->list_kref, ttm_bo_release_list);
791 return ret; 802 return ret;
@@ -849,7 +860,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
849 return ret; 860 return ret;
850 if (mem->mm_node) 861 if (mem->mm_node)
851 break; 862 break;
852 ret = ttm_mem_evict_first(bdev, mem_type, place, 863 ret = ttm_mem_evict_first(bdev, bo->resv, mem_type, place,
853 interruptible, no_wait_gpu); 864 interruptible, no_wait_gpu);
854 if (unlikely(ret != 0)) 865 if (unlikely(ret != 0))
855 return ret; 866 return ret;
@@ -1352,7 +1363,8 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
1352 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { 1363 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
1353 while (!list_empty(&man->lru[i])) { 1364 while (!list_empty(&man->lru[i])) {
1354 spin_unlock(&glob->lru_lock); 1365 spin_unlock(&glob->lru_lock);
1355 ret = ttm_mem_evict_first(bdev, mem_type, NULL, false, false); 1366 ret = ttm_mem_evict_first(bdev, NULL, mem_type, NULL,
1367 false, false);
1356 if (ret) 1368 if (ret)
1357 return ret; 1369 return ret;
1358 spin_lock(&glob->lru_lock); 1370 spin_lock(&glob->lru_lock);