For each buffer object, remember evictions and try undoing them if memory pressure gets lower again. Signed-off-by: Friedrich Vock <friedrich.vock@xxxxxx> --- drivers/gpu/drm/ttm/ttm_bo.c | 28 +++++++++++++++++++++++++++- drivers/gpu/drm/ttm/ttm_bo_util.c | 3 +++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 3968b17453569..9a0efbf79316c 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -178,6 +178,12 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) { if (bo->bdev->funcs->delete_mem_notify) bo->bdev->funcs->delete_mem_notify(bo); + if (bo->evicted_type != TTM_NUM_MEM_TYPES) { + spin_lock(&bo->bdev->unevict_lock); + list_del_init(&bo->evicted); + man->evicted_bytes -= bo->base.size; + spin_unlock(&bo->bdev->unevict_lock); + } ttm_bo_tt_destroy(bo); ttm_resource_free(bo, &bo->resource); @@ -429,7 +435,9 @@ static int ttm_bo_bounce_temp_buffer(struct ttm_buffer_object *bo, static int ttm_bo_evict(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx) { + int evicted_type = bo->resource->mem_type; struct ttm_device *bdev = bo->bdev; + struct ttm_resource_manager *man; struct ttm_resource *evict_mem; struct ttm_placement placement; struct ttm_place hop; @@ -438,6 +446,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, memset(&hop, 0, sizeof(hop)); dma_resv_assert_held(bo->base.resv); + man = ttm_manager_type(bdev, evicted_type); placement.num_placement = 0; placement.num_busy_placement = 0; @@ -477,6 +486,14 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, ttm_resource_free(bo, &evict_mem); if (ret != -ERESTARTSYS && ret != -EINTR) pr_err("Buffer eviction failed\n"); + } else if (bo->evicted_type == TTM_NUM_MEM_TYPES && + bo->bdev->funcs->uneviction_valuable && + bo->bdev->funcs->uneviction_valuable(bo)) { + bo->evicted_type = evicted_type; + spin_lock(&bo->bdev->unevict_lock); + list_add_tail(&bo->evicted, &man->evicted); + man->evicted_bytes += bo->base.size; + spin_unlock(&bo->bdev->unevict_lock); } out: return ret; @@ -845,6 +862,7 @@ static int ttm_bo_move_buffer(struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_operation_ctx *ctx) { + struct ttm_resource_manager *man; struct ttm_resource *mem; struct ttm_place hop; int ret; @@ -873,8 +891,16 @@ static int ttm_bo_move_buffer(struct ttm_buffer_object *bo, goto bounce; } out: - if (ret) + if (ret) { ttm_resource_free(bo, &mem); + } else if (bo->evicted_type != TTM_NUM_MEM_TYPES) { + man = ttm_manager_type(bo->bdev, bo->evicted_type); + spin_lock(&bo->bdev->unevict_lock); + list_del_init(&bo->evicted); + man->evicted_bytes -= bo->base.size; + spin_unlock(&bo->bdev->unevict_lock); + bo->evicted_type = TTM_NUM_MEM_TYPES; + } return ret; } diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index fd9fd3d15101c..119291c5ed85e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -262,6 +262,9 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, fbo->base.bulk_move = NULL; } + INIT_LIST_HEAD(&fbo->base.evicted); + fbo->base.evicted_type = TTM_NUM_MEM_TYPES; + ret = dma_resv_reserve_fences(&fbo->base.base._resv, 1); if (ret) { kfree(fbo); -- 2.44.0