This adds support to enable a placement only when a certain treshold of moved bytes is reached. It's a context flag which will be handled together with TTM_PL_FLAG_DESIRED and TTM_PL_FLAG_FALLBACK. Signed-off-by: Christian König <christian.koenig@xxxxxxx> --- drivers/gpu/drm/ttm/ttm_bo.c | 5 ++--- drivers/gpu/drm/ttm/ttm_resource.c | 35 ++++++++++++++++++++++++++++-- include/drm/ttm/ttm_bo.h | 3 +++ include/drm/ttm/ttm_placement.h | 15 +++++++++++++ include/drm/ttm/ttm_resource.h | 2 ++ 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 6396dece0db1..6cd2e32bb5db 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -764,8 +764,7 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo, if (!man || !ttm_resource_manager_used(man)) continue; - if (place->flags & (force_space ? TTM_PL_FLAG_DESIRED : - TTM_PL_FLAG_FALLBACK)) + if (!ttm_place_applicable(place, ctx, force_space)) continue; do { @@ -864,7 +863,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, do { /* Check whether we need to move buffer. */ if (bo->resource && - ttm_resource_compatible(bo->resource, placement, + ttm_resource_compatible(bo->resource, placement, ctx, force_space)) return 0; diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 4a66b851b67d..74a6bfc74dbe 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -292,6 +292,37 @@ bool ttm_resource_intersects(struct ttm_device *bdev, return man->func->intersects(man, res, place, size); } +/** + * ttm_place_applicable - check if place is applicable + * + * @place: place to check + * @ctx: the operation context + * @evicting: true if TTM is evicting resources + * + * Return true if the place is currently applicable. + */ +bool ttm_place_applicable(const struct ttm_place *place, + struct ttm_operation_ctx *ctx, + bool evicting) +{ + + /* When no flag is given we always consider the place applicable */ + if (!(place->flags & TTM_PL_FLAG_CTX_MASK)) + return true; + + if (place->flags & TTM_PL_FLAG_FALLBACK && evicting) + return true; + + if (place->flags & TTM_PL_FLAG_DESIRED && !evicting) + return true; + + if (place->flags & TTM_PL_FLAG_MOVE_THRESHOLD && + ctx->bytes_moved < ctx->move_threshold) + return true; + + return false; +} + /** * ttm_resource_compatible - check if resource is compatible with placement * @@ -303,6 +334,7 @@ bool ttm_resource_intersects(struct ttm_device *bdev, */ bool ttm_resource_compatible(struct ttm_resource *res, struct ttm_placement *placement, + struct ttm_operation_ctx *ctx, bool evicting) { struct ttm_buffer_object *bo = res->bo; @@ -319,8 +351,7 @@ bool ttm_resource_compatible(struct ttm_resource *res, if (res->mem_type != place->mem_type) continue; - if (place->flags & (evicting ? TTM_PL_FLAG_DESIRED : - TTM_PL_FLAG_FALLBACK)) + if (!ttm_place_applicable(place, ctx, evicting)) continue; if (place->flags & TTM_PL_FLAG_CONTIGUOUS && diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h index 6ccf96c91f3a..a85be2140970 100644 --- a/include/drm/ttm/ttm_bo.h +++ b/include/drm/ttm/ttm_bo.h @@ -176,6 +176,8 @@ struct ttm_bo_kmap_obj { * faults. Should only be used by TTM internally. * @resv: Reservation object to allow reserved evictions with. * @bytes_moved: Statistics on how many bytes have been moved. + * @move_threshold: When @bytes_moved >= @move_threshold placements with + * @TTM_PL_FLAG_MOVE_TRESHOLD are used as well. * * Context for TTM operations like changing buffer placement or general memory * allocation. @@ -188,6 +190,7 @@ struct ttm_operation_ctx { bool force_alloc; struct dma_resv *resv; uint64_t bytes_moved; + uint64_t move_threshold; }; /** diff --git a/include/drm/ttm/ttm_placement.h b/include/drm/ttm/ttm_placement.h index b510a4812609..cf809749585d 100644 --- a/include/drm/ttm/ttm_placement.h +++ b/include/drm/ttm/ttm_placement.h @@ -48,6 +48,8 @@ * placement that can handle such scenarios is a good idea. */ +struct ttm_operation_ctx; + #define TTM_PL_SYSTEM 0 #define TTM_PL_TT 1 #define TTM_PL_VRAM 2 @@ -70,6 +72,15 @@ /* Placement is only used during eviction */ #define TTM_PL_FLAG_FALLBACK (1 << 4) +/* Placement can only be used if threshold of moved bytes is reached */ +#define TTM_PL_FLAG_MOVE_THRESHOLD (1 << 5) + +/* Placement flags which depend on TTMs operation ctx. Fulfilling any flag is + * enough to consider the placement applicable. + */ +#define TTM_PL_FLAG_CTX_MASK (TTM_PL_FLAG_DESIRED | TTM_PL_FLAG_FALLBACK | \ + TTM_PL_FLAG_MOVE_THRESHOLD) + /** * struct ttm_place * @@ -100,4 +111,8 @@ struct ttm_placement { const struct ttm_place *placement; }; +bool ttm_place_applicable(const struct ttm_place *place, + struct ttm_operation_ctx *ctx, + bool evicting); + #endif diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h index 69769355139f..6ca6b7b82fb8 100644 --- a/include/drm/ttm/ttm_resource.h +++ b/include/drm/ttm/ttm_resource.h @@ -44,6 +44,7 @@ struct ttm_resource; struct ttm_place; struct ttm_buffer_object; struct ttm_placement; +struct ttm_operation_ctx; struct iosys_map; struct io_mapping; struct sg_table; @@ -370,6 +371,7 @@ bool ttm_resource_intersects(struct ttm_device *bdev, size_t size); bool ttm_resource_compatible(struct ttm_resource *res, struct ttm_placement *placement, + struct ttm_operation_ctx *ctx, bool evicting); void ttm_resource_set_bo(struct ttm_resource *res, struct ttm_buffer_object *bo); -- 2.34.1