drm/ttm: Use a struct for the common part of struct ttm_lru_walk and struct ttm_bo_lru_cursor
Let the locking functions take the new struct ttm_lru_walk_arg as argument in order for them to be easily used from both types of walk. v2: - Whitespace fix Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Christian König <christian.koenig@amd.com> Link: https://lore.kernel.org/r/20250623155313.4901-2-thomas.hellstrom@linux.intel.com
This commit is contained in:
@@ -526,11 +526,11 @@ static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *
|
||||
return 0;
|
||||
|
||||
if (bo->deleted) {
|
||||
lret = ttm_bo_wait_ctx(bo, walk->ctx);
|
||||
lret = ttm_bo_wait_ctx(bo, walk->arg.ctx);
|
||||
if (!lret)
|
||||
ttm_bo_cleanup_memtype_use(bo);
|
||||
} else {
|
||||
lret = ttm_bo_evict(bo, walk->ctx);
|
||||
lret = ttm_bo_evict(bo, walk->arg.ctx);
|
||||
}
|
||||
|
||||
if (lret)
|
||||
@@ -566,8 +566,10 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,
|
||||
struct ttm_bo_evict_walk evict_walk = {
|
||||
.walk = {
|
||||
.ops = &ttm_evict_walk_ops,
|
||||
.ctx = ctx,
|
||||
.ticket = ticket,
|
||||
.arg = {
|
||||
.ctx = ctx,
|
||||
.ticket = ticket,
|
||||
}
|
||||
},
|
||||
.place = place,
|
||||
.evictor = evictor,
|
||||
@@ -576,7 +578,7 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,
|
||||
};
|
||||
s64 lret;
|
||||
|
||||
evict_walk.walk.trylock_only = true;
|
||||
evict_walk.walk.arg.trylock_only = true;
|
||||
lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
|
||||
|
||||
/* One more attempt if we hit low limit? */
|
||||
@@ -590,12 +592,12 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,
|
||||
/* Reset low limit */
|
||||
evict_walk.try_low = evict_walk.hit_low = false;
|
||||
/* If ticket-locking, repeat while making progress. */
|
||||
evict_walk.walk.trylock_only = false;
|
||||
evict_walk.walk.arg.trylock_only = false;
|
||||
|
||||
retry:
|
||||
do {
|
||||
/* The walk may clear the evict_walk.walk.ticket field */
|
||||
evict_walk.walk.ticket = ticket;
|
||||
evict_walk.walk.arg.ticket = ticket;
|
||||
evict_walk.evicted = 0;
|
||||
lret = ttm_lru_walk_for_evict(&evict_walk.walk, bdev, man, 1);
|
||||
} while (!lret && evict_walk.evicted);
|
||||
@@ -1106,7 +1108,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
|
||||
struct ttm_place place = {.mem_type = bo->resource->mem_type};
|
||||
struct ttm_bo_swapout_walk *swapout_walk =
|
||||
container_of(walk, typeof(*swapout_walk), walk);
|
||||
struct ttm_operation_ctx *ctx = walk->ctx;
|
||||
struct ttm_operation_ctx *ctx = walk->arg.ctx;
|
||||
s64 ret;
|
||||
|
||||
/*
|
||||
@@ -1217,8 +1219,10 @@ s64 ttm_bo_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
|
||||
struct ttm_bo_swapout_walk swapout_walk = {
|
||||
.walk = {
|
||||
.ops = &ttm_swap_ops,
|
||||
.ctx = ctx,
|
||||
.trylock_only = true,
|
||||
.arg = {
|
||||
.ctx = ctx,
|
||||
.trylock_only = true,
|
||||
},
|
||||
},
|
||||
.gfp_flags = gfp_flags,
|
||||
};
|
||||
|
||||
@@ -773,10 +773,12 @@ error_destroy_tt:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool ttm_lru_walk_trylock(struct ttm_operation_ctx *ctx,
|
||||
static bool ttm_lru_walk_trylock(struct ttm_lru_walk_arg *arg,
|
||||
struct ttm_buffer_object *bo,
|
||||
bool *needs_unlock)
|
||||
{
|
||||
struct ttm_operation_ctx *ctx = arg->ctx;
|
||||
|
||||
*needs_unlock = false;
|
||||
|
||||
if (dma_resv_trylock(bo->base.resv)) {
|
||||
@@ -792,17 +794,17 @@ static bool ttm_lru_walk_trylock(struct ttm_operation_ctx *ctx,
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ttm_lru_walk_ticketlock(struct ttm_lru_walk *walk,
|
||||
static int ttm_lru_walk_ticketlock(struct ttm_lru_walk_arg *arg,
|
||||
struct ttm_buffer_object *bo,
|
||||
bool *needs_unlock)
|
||||
{
|
||||
struct dma_resv *resv = bo->base.resv;
|
||||
int ret;
|
||||
|
||||
if (walk->ctx->interruptible)
|
||||
ret = dma_resv_lock_interruptible(resv, walk->ticket);
|
||||
if (arg->ctx->interruptible)
|
||||
ret = dma_resv_lock_interruptible(resv, arg->ticket);
|
||||
else
|
||||
ret = dma_resv_lock(resv, walk->ticket);
|
||||
ret = dma_resv_lock(resv, arg->ticket);
|
||||
|
||||
if (!ret) {
|
||||
*needs_unlock = true;
|
||||
@@ -812,7 +814,7 @@ static int ttm_lru_walk_ticketlock(struct ttm_lru_walk *walk,
|
||||
* after waiting for the ticketlock, revert back to
|
||||
* trylocking for this walk.
|
||||
*/
|
||||
walk->ticket = NULL;
|
||||
arg->ticket = NULL;
|
||||
} else if (ret == -EDEADLK) {
|
||||
/* Caller needs to exit the ww transaction. */
|
||||
ret = -ENOSPC;
|
||||
@@ -879,10 +881,10 @@ s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
|
||||
* since if we do it the other way around, and the trylock fails,
|
||||
* we need to drop the lru lock to put the bo.
|
||||
*/
|
||||
if (ttm_lru_walk_trylock(walk->ctx, bo, &bo_needs_unlock))
|
||||
if (ttm_lru_walk_trylock(&walk->arg, bo, &bo_needs_unlock))
|
||||
bo_locked = true;
|
||||
else if (!walk->ticket || walk->ctx->no_wait_gpu ||
|
||||
walk->trylock_only)
|
||||
else if (!walk->arg.ticket || walk->arg.ctx->no_wait_gpu ||
|
||||
walk->arg.trylock_only)
|
||||
continue;
|
||||
|
||||
if (!ttm_bo_get_unless_zero(bo)) {
|
||||
@@ -895,7 +897,7 @@ s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
|
||||
|
||||
lret = 0;
|
||||
if (!bo_locked)
|
||||
lret = ttm_lru_walk_ticketlock(walk, bo, &bo_needs_unlock);
|
||||
lret = ttm_lru_walk_ticketlock(&walk->arg, bo, &bo_needs_unlock);
|
||||
|
||||
/*
|
||||
* Note that in between the release of the lru lock and the
|
||||
@@ -972,7 +974,7 @@ ttm_bo_lru_cursor_init(struct ttm_bo_lru_cursor *curs,
|
||||
{
|
||||
memset(curs, 0, sizeof(*curs));
|
||||
ttm_resource_cursor_init(&curs->res_curs, man);
|
||||
curs->ctx = ctx;
|
||||
curs->arg.ctx = ctx;
|
||||
|
||||
return curs;
|
||||
}
|
||||
@@ -983,7 +985,7 @@ ttm_bo_from_res_reserved(struct ttm_resource *res, struct ttm_bo_lru_cursor *cur
|
||||
{
|
||||
struct ttm_buffer_object *bo = res->bo;
|
||||
|
||||
if (!ttm_lru_walk_trylock(curs->ctx, bo, &curs->needs_unlock))
|
||||
if (!ttm_lru_walk_trylock(&curs->arg, bo, &curs->needs_unlock))
|
||||
return NULL;
|
||||
|
||||
if (!ttm_bo_get_unless_zero(bo)) {
|
||||
|
||||
@@ -207,11 +207,9 @@ struct ttm_lru_walk_ops {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ttm_lru_walk - Structure describing a LRU walk.
|
||||
* struct ttm_lru_walk_arg - Common part for the variants of BO LRU walk.
|
||||
*/
|
||||
struct ttm_lru_walk {
|
||||
/** @ops: Pointer to the ops structure. */
|
||||
const struct ttm_lru_walk_ops *ops;
|
||||
struct ttm_lru_walk_arg {
|
||||
/** @ctx: Pointer to the struct ttm_operation_ctx. */
|
||||
struct ttm_operation_ctx *ctx;
|
||||
/** @ticket: The struct ww_acquire_ctx if any. */
|
||||
@@ -220,6 +218,16 @@ struct ttm_lru_walk {
|
||||
bool trylock_only;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ttm_lru_walk - Structure describing a LRU walk.
|
||||
*/
|
||||
struct ttm_lru_walk {
|
||||
/** @ops: Pointer to the ops structure. */
|
||||
const struct ttm_lru_walk_ops *ops;
|
||||
/** @arg: Common bo LRU walk arguments. */
|
||||
struct ttm_lru_walk_arg arg;
|
||||
};
|
||||
|
||||
s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
|
||||
struct ttm_resource_manager *man, s64 target);
|
||||
|
||||
@@ -466,11 +474,6 @@ int ttm_bo_populate(struct ttm_buffer_object *bo,
|
||||
struct ttm_bo_lru_cursor {
|
||||
/** @res_curs: Embedded struct ttm_resource_cursor. */
|
||||
struct ttm_resource_cursor res_curs;
|
||||
/**
|
||||
* @ctx: The struct ttm_operation_ctx used while looping.
|
||||
* governs the locking mode.
|
||||
*/
|
||||
struct ttm_operation_ctx *ctx;
|
||||
/**
|
||||
* @bo: Buffer object pointer if a buffer object is refcounted,
|
||||
* NULL otherwise.
|
||||
@@ -481,6 +484,8 @@ struct ttm_bo_lru_cursor {
|
||||
* unlock before the next iteration or after loop exit.
|
||||
*/
|
||||
bool needs_unlock;
|
||||
/** @arg: Common BO LRU walk arguments. */
|
||||
struct ttm_lru_walk_arg arg;
|
||||
};
|
||||
|
||||
void ttm_bo_lru_cursor_fini(struct ttm_bo_lru_cursor *curs);
|
||||
|
||||
Reference in New Issue
Block a user