drm/ttm: add new function to check if bo is allowable to evict or swapout

extract a function as ttm_bo_evict_swapout_allowable since eviction and
swapout can share same logic.

v2: modify commit message and add description in the code

Reviewed-by: Thomas Hellström <thellstrom@vmware.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chuming Zhou <david1.zhou@amd.com>
Signed-off-by: Roger He <Hongbo.He@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Roger He 2017-12-21 17:42:52 +08:00 committed by Alex Deucher
parent 993baf1556
commit d5769ba315
1 changed files with 30 additions and 10 deletions

View File

@ -708,6 +708,34 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
}
EXPORT_SYMBOL(ttm_bo_eviction_valuable);
/**
* Check the target bo is allowable to be evicted or swapout, including cases:
*
* a. if share same reservation object with ctx->resv, have assumption
* reservation objects should already be locked, so not lock again and
* return true directly when either the opreation allow_reserved_eviction
* or the target bo already is in delayed free list;
*
* b. Otherwise, trylock it.
*/
static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
struct ttm_operation_ctx *ctx, bool *locked)
{
bool ret = false;
*locked = false;
if (bo->resv == ctx->resv) {
reservation_object_assert_held(bo->resv);
if (ctx->allow_reserved_eviction || !list_empty(&bo->ddestroy))
ret = true;
} else {
*locked = reservation_object_trylock(bo->resv);
ret = *locked;
}
return ret;
}
static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
uint32_t mem_type,
const struct ttm_place *place,
@ -723,21 +751,13 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
spin_lock(&glob->lru_lock);
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
list_for_each_entry(bo, &man->lru[i], lru) {
if (bo->resv == ctx->resv) {
if (!ctx->allow_reserved_eviction &&
list_empty(&bo->ddestroy))
if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked))
continue;
} else {
locked = reservation_object_trylock(bo->resv);
if (!locked)
continue;
}
if (place && !bdev->driver->eviction_valuable(bo,
place)) {
if (locked)
reservation_object_unlock(bo->resv);
locked = false;
continue;
}
break;