1
0
Fork 0

drm/ttm: cleanup ttm_bo_mem_space

We tried this once before, but that turned out to be more
complicated than thought. With all the right prerequisites
it looks like we can do this now.

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Chunming Zhou <david1.zhou@amd.com>
Tested-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
alistair/sunxi64-5.4-dsi
Christian König 2019-05-13 17:34:29 +02:00 committed by Alex Deucher
parent af1dac01a7
commit 4c5ac9487c
1 changed files with 66 additions and 61 deletions

View File

@ -893,13 +893,12 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo,
* space, or we've evicted everything and there isn't enough space.
*/
static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
uint32_t mem_type,
const struct ttm_place *place,
struct ttm_mem_reg *mem,
struct ttm_operation_ctx *ctx)
const struct ttm_place *place,
struct ttm_mem_reg *mem,
struct ttm_operation_ctx *ctx)
{
struct ttm_bo_device *bdev = bo->bdev;
struct ttm_mem_type_manager *man = &bdev->man[mem_type];
struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
int ret;
do {
@ -908,11 +907,11 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
return ret;
if (mem->mm_node)
break;
ret = ttm_mem_evict_first(bdev, mem_type, place, ctx);
ret = ttm_mem_evict_first(bdev, mem->mem_type, place, ctx);
if (unlikely(ret != 0))
return ret;
} while (1);
mem->mem_type = mem_type;
return ttm_bo_add_move_fence(bo, man, mem);
}
@ -960,6 +959,51 @@ static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
return true;
}
/**
* ttm_bo_mem_placement - check if placement is compatible
* @bo: BO to find memory for
* @place: where to search
* @mem: the memory object to fill in
* @ctx: operation context
*
* Check if placement is compatible and fill in mem structure.
* Returns -EBUSY if placement won't work or negative error code.
* 0 when placement can be used.
*/
static int ttm_bo_mem_placement(struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_mem_reg *mem,
struct ttm_operation_ctx *ctx)
{
struct ttm_bo_device *bdev = bo->bdev;
uint32_t mem_type = TTM_PL_SYSTEM;
struct ttm_mem_type_manager *man;
uint32_t cur_flags = 0;
int ret;
ret = ttm_mem_type_from_place(place, &mem_type);
if (ret)
return ret;
man = &bdev->man[mem_type];
if (!man->has_type || !man->use_type)
return -EBUSY;
if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))
return -EBUSY;
cur_flags = ttm_bo_select_caching(man, bo->mem.placement, cur_flags);
/*
* Use the access and other non-mapping-related flag bits from
* the memory placement flags to the current flags
*/
ttm_flag_masked(&cur_flags, place->flags, ~TTM_PL_MASK_MEMTYPE);
mem->mem_type = mem_type;
mem->placement = cur_flags;
return 0;
}
/**
* Creates space for memory region @mem according to its type.
*
@ -974,11 +1018,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
struct ttm_operation_ctx *ctx)
{
struct ttm_bo_device *bdev = bo->bdev;
struct ttm_mem_type_manager *man;
uint32_t mem_type = TTM_PL_SYSTEM;
uint32_t cur_flags = 0;
bool type_found = false;
bool type_ok = false;
int i, ret;
ret = reservation_object_reserve_shared(bo->resv, 1);
@ -988,37 +1028,20 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
mem->mm_node = NULL;
for (i = 0; i < placement->num_placement; ++i) {
const struct ttm_place *place = &placement->placement[i];
struct ttm_mem_type_manager *man;
ret = ttm_mem_type_from_place(place, &mem_type);
ret = ttm_bo_mem_placement(bo, place, mem, ctx);
if (ret == -EBUSY)
continue;
if (ret)
return ret;
man = &bdev->man[mem_type];
if (!man->has_type || !man->use_type)
continue;
type_ok = ttm_bo_mt_compatible(man, mem_type, place,
&cur_flags);
if (!type_ok)
continue;
type_found = true;
cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
cur_flags);
/*
* Use the access and other non-mapping-related flag bits from
* the memory placement flags to the current flags
*/
ttm_flag_masked(&cur_flags, place->flags,
~TTM_PL_MASK_MEMTYPE);
if (mem_type == TTM_PL_SYSTEM) {
mem->mem_type = mem_type;
mem->placement = cur_flags;
mem->mm_node = NULL;
mem->mm_node = NULL;
if (mem->mem_type == TTM_PL_SYSTEM)
return 0;
}
man = &bdev->man[mem->mem_type];
ret = (*man->func->get_node)(man, bo, place, mem);
if (unlikely(ret))
return ret;
@ -1029,8 +1052,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
(*man->func->put_node)(man, mem);
return ret;
}
mem->mem_type = mem_type;
mem->placement = cur_flags;
return 0;
}
}
@ -1038,37 +1059,21 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
for (i = 0; i < placement->num_busy_placement; ++i) {
const struct ttm_place *place = &placement->busy_placement[i];
ret = ttm_mem_type_from_place(place, &mem_type);
ret = ttm_bo_mem_placement(bo, place, mem, ctx);
if (ret == -EBUSY)
continue;
if (ret)
return ret;
man = &bdev->man[mem_type];
if (!man->has_type || !man->use_type)
continue;
if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))
continue;
type_found = true;
cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
cur_flags);
/*
* Use the access and other non-mapping-related flag bits from
* the memory placement flags to the current flags
*/
ttm_flag_masked(&cur_flags, place->flags,
~TTM_PL_MASK_MEMTYPE);
if (mem_type == TTM_PL_SYSTEM) {
mem->mem_type = mem_type;
mem->placement = cur_flags;
mem->mm_node = NULL;
mem->mm_node = NULL;
if (mem->mem_type == TTM_PL_SYSTEM)
return 0;
}
ret = ttm_bo_mem_force_space(bo, mem_type, place, mem, ctx);
if (ret == 0 && mem->mm_node) {
mem->placement = cur_flags;
ret = ttm_bo_mem_force_space(bo, place, mem, ctx);
if (ret == 0 && mem->mm_node)
return 0;
}
if (ret && ret != -EBUSY)
return ret;
}