Skip to content

Commit 70d645d

Browse files
author
Thomas Hellström
committed
drm/ttm: Add helpers for shrinking
Add a number of helpers for shrinking that access core TTM and core MM functionality in a way that make them unsuitable for driver open-coding. v11: - New patch (split off from previous) and additional helpers. v13: - Adapt to ttm_backup interface change. - Take resource off LRU when backed up. Signed-off-by: Thomas Hellström <[email protected]> Reviewed-by: Matthew Brost <[email protected]> Acked-by: Dave Airlie <[email protected]> Acked-by: Christian König <[email protected]> Link: https://lore.kernel.org/intel-xe/[email protected]
1 parent f3bcfd0 commit 70d645d

File tree

4 files changed

+158
-1
lines changed

4 files changed

+158
-1
lines changed

drivers/gpu/drm/ttm/ttm_bo_util.c

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
/*
2929
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
3030
*/
31-
31+
#include <linux/swap.h>
3232
#include <linux/vmalloc.h>
3333

3434
#include <drm/ttm/ttm_bo.h>
@@ -1052,3 +1052,108 @@ struct ttm_buffer_object *ttm_bo_lru_cursor_first(struct ttm_bo_lru_cursor *curs
10521052
return bo ? bo : ttm_bo_lru_cursor_next(curs);
10531053
}
10541054
EXPORT_SYMBOL(ttm_bo_lru_cursor_first);
1055+
1056+
/**
1057+
* ttm_bo_shrink() - Helper to shrink a ttm buffer object.
1058+
* @ctx: The struct ttm_operation_ctx used for the shrinking operation.
1059+
* @bo: The buffer object.
1060+
* @flags: Flags governing the shrinking behaviour.
1061+
*
1062+
* The function uses the ttm_tt_back_up functionality to back up or
1063+
* purge a struct ttm_tt. If the bo is not in system, it's first
1064+
* moved there.
1065+
*
1066+
* Return: The number of pages shrunken or purged, or
1067+
* negative error code on failure.
1068+
*/
1069+
long ttm_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo,
1070+
const struct ttm_bo_shrink_flags flags)
1071+
{
1072+
static const struct ttm_place sys_placement_flags = {
1073+
.fpfn = 0,
1074+
.lpfn = 0,
1075+
.mem_type = TTM_PL_SYSTEM,
1076+
.flags = 0,
1077+
};
1078+
static struct ttm_placement sys_placement = {
1079+
.num_placement = 1,
1080+
.placement = &sys_placement_flags,
1081+
};
1082+
struct ttm_tt *tt = bo->ttm;
1083+
long lret;
1084+
1085+
dma_resv_assert_held(bo->base.resv);
1086+
1087+
if (flags.allow_move && bo->resource->mem_type != TTM_PL_SYSTEM) {
1088+
int ret = ttm_bo_validate(bo, &sys_placement, ctx);
1089+
1090+
/* Consider -ENOMEM and -ENOSPC non-fatal. */
1091+
if (ret) {
1092+
if (ret == -ENOMEM || ret == -ENOSPC)
1093+
ret = -EBUSY;
1094+
return ret;
1095+
}
1096+
}
1097+
1098+
ttm_bo_unmap_virtual(bo);
1099+
lret = ttm_bo_wait_ctx(bo, ctx);
1100+
if (lret < 0)
1101+
return lret;
1102+
1103+
if (bo->bulk_move) {
1104+
spin_lock(&bo->bdev->lru_lock);
1105+
ttm_resource_del_bulk_move(bo->resource, bo);
1106+
spin_unlock(&bo->bdev->lru_lock);
1107+
}
1108+
1109+
lret = ttm_tt_backup(bo->bdev, tt, (struct ttm_backup_flags)
1110+
{.purge = flags.purge,
1111+
.writeback = flags.writeback});
1112+
1113+
if (lret <= 0 && bo->bulk_move) {
1114+
spin_lock(&bo->bdev->lru_lock);
1115+
ttm_resource_add_bulk_move(bo->resource, bo);
1116+
spin_unlock(&bo->bdev->lru_lock);
1117+
}
1118+
1119+
if (lret < 0 && lret != -EINTR)
1120+
return -EBUSY;
1121+
1122+
return lret;
1123+
}
1124+
EXPORT_SYMBOL(ttm_bo_shrink);
1125+
1126+
/**
1127+
* ttm_bo_shrink_suitable() - Whether a bo is suitable for shinking
1128+
* @ctx: The struct ttm_operation_ctx governing the shrinking.
1129+
* @bo: The candidate for shrinking.
1130+
*
1131+
* Check whether the object, given the information available to TTM,
1132+
* is suitable for shinking, This function can and should be used
1133+
* before attempting to shrink an object.
1134+
*
1135+
* Return: true if suitable. false if not.
1136+
*/
1137+
bool ttm_bo_shrink_suitable(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx)
1138+
{
1139+
return bo->ttm && ttm_tt_is_populated(bo->ttm) && !bo->pin_count &&
1140+
(!ctx->no_wait_gpu ||
1141+
dma_resv_test_signaled(bo->base.resv, DMA_RESV_USAGE_BOOKKEEP));
1142+
}
1143+
EXPORT_SYMBOL(ttm_bo_shrink_suitable);
1144+
1145+
/**
1146+
* ttm_bo_shrink_avoid_wait() - Whether to avoid waiting for GPU
1147+
* during shrinking
1148+
*
1149+
* In some situations, like direct reclaim, waiting (in particular gpu waiting)
1150+
* should be avoided since it may stall a system that could otherwise make progress
1151+
* shrinking something else less time consuming.
1152+
*
1153+
* Return: true if gpu waiting should be avoided, false if not.
1154+
*/
1155+
bool ttm_bo_shrink_avoid_wait(void)
1156+
{
1157+
return !current_is_kswapd();
1158+
}
1159+
EXPORT_SYMBOL(ttm_bo_shrink_avoid_wait);

drivers/gpu/drm/ttm/ttm_tt.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,3 +531,32 @@ unsigned long ttm_tt_pages_limit(void)
531531
return ttm_pages_limit;
532532
}
533533
EXPORT_SYMBOL(ttm_tt_pages_limit);
534+
535+
/**
536+
* ttm_tt_setup_backup() - Allocate and assign a backup structure for a ttm_tt
537+
* @tt: The ttm_tt for wich to allocate and assign a backup structure.
538+
*
539+
* Assign a backup structure to be used for tt backup. This should
540+
* typically be done at bo creation, to avoid allocations at shrinking
541+
* time.
542+
*
543+
* Return: 0 on success, negative error code on failure.
544+
*/
545+
int ttm_tt_setup_backup(struct ttm_tt *tt)
546+
{
547+
struct ttm_backup *backup =
548+
ttm_backup_shmem_create(((loff_t)tt->num_pages) << PAGE_SHIFT);
549+
550+
if (WARN_ON_ONCE(!(tt->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE)))
551+
return -EINVAL;
552+
553+
if (IS_ERR(backup))
554+
return PTR_ERR(backup);
555+
556+
if (tt->backup)
557+
ttm_backup_fini(tt->backup);
558+
559+
tt->backup = backup;
560+
return 0;
561+
}
562+
EXPORT_SYMBOL(ttm_tt_setup_backup);

include/drm/ttm/ttm_bo.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,27 @@ struct ttm_lru_walk {
225225
s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
226226
struct ttm_resource_manager *man, s64 target);
227227

228+
/**
229+
* struct ttm_bo_shrink_flags - flags to govern the bo shrinking behaviour
230+
* @purge: Purge the content rather than backing it up.
231+
* @writeback: Attempt to immediately write content to swap space.
232+
* @allow_move: Allow moving to system before shrinking. This is typically
233+
* not desired for zombie- or ghost objects (with zombie object meaning
234+
* objects with a zero gem object refcount)
235+
*/
236+
struct ttm_bo_shrink_flags {
237+
u32 purge : 1;
238+
u32 writeback : 1;
239+
u32 allow_move : 1;
240+
};
241+
242+
long ttm_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo,
243+
const struct ttm_bo_shrink_flags flags);
244+
245+
bool ttm_bo_shrink_suitable(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx);
246+
247+
bool ttm_bo_shrink_avoid_wait(void);
248+
228249
/**
229250
* ttm_bo_get - reference a struct ttm_buffer_object
230251
*

include/drm/ttm/ttm_tt.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ long ttm_tt_backup(struct ttm_device *bdev, struct ttm_tt *tt,
298298
int ttm_tt_restore(struct ttm_device *bdev, struct ttm_tt *tt,
299299
const struct ttm_operation_ctx *ctx);
300300

301+
int ttm_tt_setup_backup(struct ttm_tt *tt);
302+
301303
#if IS_ENABLED(CONFIG_AGP)
302304
#include <linux/agp_backend.h>
303305

0 commit comments

Comments
 (0)