From: Christian König christian.koenig@amd.com
That is completely nonsense. If we blindly continue we would end up in an endless loop trying to evict the same BOs over and over again.
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/ttm/ttm_bo.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index e340d0d6..66c50ad 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1283,7 +1283,7 @@ int ttm_bo_create(struct ttm_bo_device *bdev, EXPORT_SYMBOL(ttm_bo_create);
static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, - unsigned mem_type, bool allow_errors) + unsigned mem_type) { struct ttm_mem_type_manager *man = &bdev->man[mem_type]; struct ttm_bo_global *glob = bdev->glob; @@ -1298,13 +1298,8 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, while (!list_empty(&man->lru)) { spin_unlock(&glob->lru_lock); ret = ttm_mem_evict_first(bdev, mem_type, NULL, false, false); - if (ret) { - if (allow_errors) { - return ret; - } else { - pr_err("Cleanup eviction failed\n"); - } - } + if (ret) + return ret; spin_lock(&glob->lru_lock); } spin_unlock(&glob->lru_lock); @@ -1316,13 +1311,8 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, if (fence) { ret = fence_wait(fence, false); fence_put(fence); - if (ret) { - if (allow_errors) { - return ret; - } else { - pr_err("Cleanup eviction failed\n"); - } - } + if (ret) + return ret; }
return 0; @@ -1351,7 +1341,9 @@ int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
ret = 0; if (mem_type > 0) { - ttm_bo_force_list_clean(bdev, mem_type, false); + ret = ttm_bo_force_list_clean(bdev, mem_type); + if (ret) + pr_err("Cleanup eviction failed (%d)\n", ret);
ret = (*man->func->takedown)(man); } @@ -1374,7 +1366,7 @@ int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type) return 0; }
- return ttm_bo_force_list_clean(bdev, mem_type, true); + return ttm_bo_force_list_clean(bdev, mem_type); } EXPORT_SYMBOL(ttm_bo_evict_mm);
From: Christian König christian.koenig@amd.com
Could be faster on the read path.
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/ttm/ttm_bo.c | 16 ++++++++++------ drivers/gpu/drm/ttm/ttm_bo_util.c | 8 +++++--- 2 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 66c50ad..7e30f3b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -797,9 +797,11 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo, struct fence *fence; int ret;
- spin_lock(&man->move_lock); - fence = fence_get(man->move); - spin_unlock(&man->move_lock); + rcu_read_lock(); + do + fence = rcu_dereference(man->move); + while (unlikely(fence && !fence_get_rcu(fence))); + rcu_read_unlock();
if (fence) { reservation_object_add_shared_fence(bo->resv, fence); @@ -1304,9 +1306,11 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, } spin_unlock(&glob->lru_lock);
- spin_lock(&man->move_lock); - fence = fence_get(man->move); - spin_unlock(&man->move_lock); + rcu_read_lock(); + do + fence = rcu_dereference(man->move); + while (unlikely(fence && !fence_get_rcu(fence))); + rcu_read_unlock();
if (fence) { ret = fence_wait(fence, false); diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 4da0e78..fcd2431 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -746,6 +746,7 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, ttm_bo_unref(&ghost_obj);
} else if (from->flags & TTM_MEMTYPE_FLAG_FIXED) { + struct fence *old;
/** * BO doesn't have a TTM we need to bind/unbind. Just remember @@ -753,9 +754,10 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, */
spin_lock(&from->move_lock); - if (!from->move || fence_is_later(fence, from->move)) { - fence_put(from->move); - from->move = fence_get(fence); + old = rcu_dereference_protected(from->move, 1); + if (!old || fence_is_later(fence, old)) { + rcu_assign_pointer(from->move, fence_get(fence)); + fence_put(old); } spin_unlock(&from->move_lock);
On Tue, Jul 5, 2016 at 8:30 AM, Christian König deathsimple@vodafone.de wrote:
From: Christian König christian.koenig@amd.com
Could be faster on the read path.
Signed-off-by: Christian König christian.koenig@amd.com
Just one style nit pick below. Beyond that, the series is: Reviewed-by: Alex Deucher alexander.deucher@amd.com
drivers/gpu/drm/ttm/ttm_bo.c | 16 ++++++++++------ drivers/gpu/drm/ttm/ttm_bo_util.c | 8 +++++--- 2 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 66c50ad..7e30f3b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -797,9 +797,11 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo, struct fence *fence; int ret;
spin_lock(&man->move_lock);
fence = fence_get(man->move);
spin_unlock(&man->move_lock);
rcu_read_lock();
do
fence = rcu_dereference(man->move);
while (unlikely(fence && !fence_get_rcu(fence)));
I generally like to see parens with do/while loops.
rcu_read_unlock(); if (fence) { reservation_object_add_shared_fence(bo->resv, fence);
@@ -1304,9 +1306,11 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, } spin_unlock(&glob->lru_lock);
spin_lock(&man->move_lock);
fence = fence_get(man->move);
spin_unlock(&man->move_lock);
rcu_read_lock();
do
fence = rcu_dereference(man->move);
while (unlikely(fence && !fence_get_rcu(fence)));
Same here.
rcu_read_unlock(); if (fence) { ret = fence_wait(fence, false);
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 4da0e78..fcd2431 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -746,6 +746,7 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, ttm_bo_unref(&ghost_obj);
} else if (from->flags & TTM_MEMTYPE_FLAG_FIXED) {
struct fence *old; /** * BO doesn't have a TTM we need to bind/unbind. Just remember
@@ -753,9 +754,10 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, */
spin_lock(&from->move_lock);
if (!from->move || fence_is_later(fence, from->move)) {
fence_put(from->move);
from->move = fence_get(fence);
old = rcu_dereference_protected(from->move, 1);
if (!old || fence_is_later(fence, old)) {
rcu_assign_pointer(from->move, fence_get(fence));
fence_put(old); } spin_unlock(&from->move_lock);
-- 2.5.0
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
dri-devel@lists.freedesktop.org