Allows us to gut a BO of it's backing store when the driver says that it isn't needed any more. Signed-off-by: Christian König <christian.koenig at amd.com> --- drivers/gpu/drm/ttm/ttm_bo.c | 15 ++++++++++++--- drivers/gpu/drm/ttm/ttm_bo_util.c | 24 ++++++++++++++++++++++++ include/drm/ttm/ttm_bo_driver.h | 9 +++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index ad142a92eb80..98e06f8bf23b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -622,14 +622,23 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, reservation_object_assert_held(bo->resv); + placement.num_placement = 0; + placement.num_busy_placement = 0; + bdev->driver->evict_flags(bo, &placement); + + if (!placement.num_placement && !placement.num_busy_placement) { + ret = ttm_bo_pipeline_gutting(bo); + if (ret) + return ret; + + return ttm_tt_create(bo, false); + } + evict_mem = bo->mem; evict_mem.mm_node = NULL; evict_mem.bus.io_reserved_vm = false; evict_mem.bus.io_reserved_count = 0; - placement.num_placement = 0; - placement.num_busy_placement = 0; - bdev->driver->evict_flags(bo, &placement); ret = ttm_bo_mem_space(bo, &placement, &evict_mem, ctx); if (ret) { if (ret != -ERESTARTSYS) { diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 6d6a3f46143b..1f730b3f18e5 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -801,3 +801,27 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, return 0; } EXPORT_SYMBOL(ttm_bo_pipeline_move); + +int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo) +{ + struct ttm_buffer_object *ghost; + int ret; + + ret = ttm_buffer_object_transfer(bo, &ghost); + if (ret) + return ret; + + ret = reservation_object_copy_fences(ghost->resv, bo->resv); + /* Last resort, wait for the BO to be idle when we are OOM */ + if (ret) + ttm_bo_wait(bo, false, false); + + memset(&bo->mem, 0, sizeof(bo->mem)); + bo->mem.mem_type = TTM_PL_SYSTEM; + bo->ttm = NULL; + + ttm_bo_unreserve(ghost); + ttm_bo_unref(&ghost); + + return 0; +} diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index f8e2515b401f..39cd6b086d3a 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -849,6 +849,15 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, struct dma_fence *fence, bool evict, struct ttm_mem_reg *new_mem); +/** + * ttm_bo_pipeline_gutting. + * + * @bo: A pointer to a struct ttm_buffer_object. + * + * Pipelined gutting a BO of it's backing store. + */ +int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo); + /** * ttm_io_prot * -- 2.14.1