Skip to content

Commit fc5d966

Browse files
author
Thomas Hellström
committed
drm/ttm: Move swapped objects off the manager's LRU list
Resources of swapped objects remains on the TTM_PL_SYSTEM manager's LRU list, which is bad for the LRU walk efficiency. Rename the device-wide "pinned" list to "unevictable" and move also resources of swapped-out objects to that list. An alternative would be to create an "UNEVICTABLE" priority to be able to keep the pinned- and swapped objects on their respective manager's LRU without affecting the LRU walk efficiency. v2: - Remove a bogus WARN_ON (Christian König) - Update ttm_resource_[add|del] bulk move (Christian König) - Fix TTM KUNIT tests (Intel CI) v3: - Check for non-NULL bo->resource in ttm_bo_populate(). v4: - Don't move to LRU tail during swapout until the resource is properly swapped or there was a swapout failure. (Intel Ci) - Add a newline after checkpatch check. v5: - Introduce ttm_resource_is_swapped() to avoid a corner-case where a newly created resource was considered swapped. (Intel CI) v6: - Move an assert. Cc: Christian König <[email protected]> Cc: Matthew Brost <[email protected]> Cc: <[email protected]> Signed-off-by: Thomas Hellström <[email protected]> Reviewed-by: Christian König <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 42aa18d commit fc5d966

File tree

15 files changed

+109
-27
lines changed

15 files changed

+109
-27
lines changed

drivers/gpu/drm/i915/gem/i915_gem_ttm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj,
808808
}
809809

810810
if (bo->ttm && !ttm_tt_is_populated(bo->ttm)) {
811-
ret = ttm_tt_populate(bo->bdev, bo->ttm, &ctx);
811+
ret = ttm_bo_populate(bo, &ctx);
812812
if (ret)
813813
return ret;
814814

drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
624624

625625
/* Populate ttm with pages if needed. Typically system memory. */
626626
if (ttm && (dst_man->use_tt || (ttm->page_flags & TTM_TT_FLAG_SWAPPED))) {
627-
ret = ttm_tt_populate(bo->bdev, ttm, ctx);
627+
ret = ttm_bo_populate(bo, ctx);
628628
if (ret)
629629
return ret;
630630
}

drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static int i915_ttm_backup(struct i915_gem_apply_to_region *apply,
9090
goto out_no_lock;
9191

9292
backup_bo = i915_gem_to_ttm(backup);
93-
err = ttm_tt_populate(backup_bo->bdev, backup_bo->ttm, &ctx);
93+
err = ttm_bo_populate(backup_bo, &ctx);
9494
if (err)
9595
goto out_no_populate;
9696

@@ -189,7 +189,7 @@ static int i915_ttm_restore(struct i915_gem_apply_to_region *apply,
189189
if (!backup_bo->resource)
190190
err = ttm_bo_validate(backup_bo, i915_ttm_sys_placement(), &ctx);
191191
if (!err)
192-
err = ttm_tt_populate(backup_bo->bdev, backup_bo->ttm, &ctx);
192+
err = ttm_bo_populate(backup_bo, &ctx);
193193
if (!err) {
194194
err = i915_gem_obj_copy_ttm(obj, backup, pm_apply->allow_gpu,
195195
false);

drivers/gpu/drm/ttm/tests/ttm_bo_test.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,11 +308,11 @@ static void ttm_bo_unreserve_pinned(struct kunit *test)
308308
err = ttm_resource_alloc(bo, place, &res2);
309309
KUNIT_ASSERT_EQ(test, err, 0);
310310
KUNIT_ASSERT_EQ(test,
311-
list_is_last(&res2->lru.link, &priv->ttm_dev->pinned), 1);
311+
list_is_last(&res2->lru.link, &priv->ttm_dev->unevictable), 1);
312312

313313
ttm_bo_unreserve(bo);
314314
KUNIT_ASSERT_EQ(test,
315-
list_is_last(&res1->lru.link, &priv->ttm_dev->pinned), 1);
315+
list_is_last(&res1->lru.link, &priv->ttm_dev->unevictable), 1);
316316

317317
ttm_resource_free(bo, &res1);
318318
ttm_resource_free(bo, &res2);

drivers/gpu/drm/ttm/tests/ttm_resource_test.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,18 @@ static void ttm_resource_init_pinned(struct kunit *test)
164164

165165
res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL);
166166
KUNIT_ASSERT_NOT_NULL(test, res);
167-
KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->pinned));
167+
KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->unevictable));
168168

169169
dma_resv_lock(bo->base.resv, NULL);
170170
ttm_bo_pin(bo);
171171
ttm_resource_init(bo, place, res);
172-
KUNIT_ASSERT_TRUE(test, list_is_singular(&bo->bdev->pinned));
172+
KUNIT_ASSERT_TRUE(test, list_is_singular(&bo->bdev->unevictable));
173173

174174
ttm_bo_unpin(bo);
175175
ttm_resource_fini(man, res);
176176
dma_resv_unlock(bo->base.resv);
177177

178-
KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->pinned));
178+
KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->unevictable));
179179
}
180180

181181
static void ttm_resource_fini_basic(struct kunit *test)

drivers/gpu/drm/ttm/ttm_bo.c

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
139139
goto out_err;
140140

141141
if (mem->mem_type != TTM_PL_SYSTEM) {
142-
ret = ttm_tt_populate(bo->bdev, bo->ttm, ctx);
142+
ret = ttm_bo_populate(bo, ctx);
143143
if (ret)
144144
goto out_err;
145145
}
@@ -1128,9 +1128,20 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
11281128
if (bo->bdev->funcs->swap_notify)
11291129
bo->bdev->funcs->swap_notify(bo);
11301130

1131-
if (ttm_tt_is_populated(bo->ttm))
1131+
if (ttm_tt_is_populated(bo->ttm)) {
1132+
spin_lock(&bo->bdev->lru_lock);
1133+
ttm_resource_del_bulk_move(bo->resource, bo);
1134+
spin_unlock(&bo->bdev->lru_lock);
1135+
11321136
ret = ttm_tt_swapout(bo->bdev, bo->ttm, swapout_walk->gfp_flags);
11331137

1138+
spin_lock(&bo->bdev->lru_lock);
1139+
if (ret)
1140+
ttm_resource_add_bulk_move(bo->resource, bo);
1141+
ttm_resource_move_to_lru_tail(bo->resource);
1142+
spin_unlock(&bo->bdev->lru_lock);
1143+
}
1144+
11341145
out:
11351146
/* Consider -ENOMEM and -ENOSPC non-fatal. */
11361147
if (ret == -ENOMEM || ret == -ENOSPC)
@@ -1180,3 +1191,47 @@ void ttm_bo_tt_destroy(struct ttm_buffer_object *bo)
11801191
ttm_tt_destroy(bo->bdev, bo->ttm);
11811192
bo->ttm = NULL;
11821193
}
1194+
1195+
/**
1196+
* ttm_bo_populate() - Ensure that a buffer object has backing pages
1197+
* @bo: The buffer object
1198+
* @ctx: The ttm_operation_ctx governing the operation.
1199+
*
1200+
* For buffer objects in a memory type whose manager uses
1201+
* struct ttm_tt for backing pages, ensure those backing pages
1202+
* are present and with valid content. The bo's resource is also
1203+
* placed on the correct LRU list if it was previously swapped
1204+
* out.
1205+
*
1206+
* Return: 0 if successful, negative error code on failure.
1207+
* Note: May return -EINTR or -ERESTARTSYS if @ctx::interruptible
1208+
* is set to true.
1209+
*/
1210+
int ttm_bo_populate(struct ttm_buffer_object *bo,
1211+
struct ttm_operation_ctx *ctx)
1212+
{
1213+
struct ttm_tt *tt = bo->ttm;
1214+
bool swapped;
1215+
int ret;
1216+
1217+
dma_resv_assert_held(bo->base.resv);
1218+
1219+
if (!tt)
1220+
return 0;
1221+
1222+
swapped = ttm_tt_is_swapped(tt);
1223+
ret = ttm_tt_populate(bo->bdev, tt, ctx);
1224+
if (ret)
1225+
return ret;
1226+
1227+
if (swapped && !ttm_tt_is_swapped(tt) && !bo->pin_count &&
1228+
bo->resource) {
1229+
spin_lock(&bo->bdev->lru_lock);
1230+
ttm_resource_add_bulk_move(bo->resource, bo);
1231+
ttm_resource_move_to_lru_tail(bo->resource);
1232+
spin_unlock(&bo->bdev->lru_lock);
1233+
}
1234+
1235+
return 0;
1236+
}
1237+
EXPORT_SYMBOL(ttm_bo_populate);

drivers/gpu/drm/ttm/ttm_bo_util.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
163163
src_man = ttm_manager_type(bdev, src_mem->mem_type);
164164
if (ttm && ((ttm->page_flags & TTM_TT_FLAG_SWAPPED) ||
165165
dst_man->use_tt)) {
166-
ret = ttm_tt_populate(bdev, ttm, ctx);
166+
ret = ttm_bo_populate(bo, ctx);
167167
if (ret)
168168
return ret;
169169
}
@@ -350,7 +350,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
350350

351351
BUG_ON(!ttm);
352352

353-
ret = ttm_tt_populate(bo->bdev, ttm, &ctx);
353+
ret = ttm_bo_populate(bo, &ctx);
354354
if (ret)
355355
return ret;
356356

@@ -507,7 +507,7 @@ int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map)
507507
pgprot_t prot;
508508
void *vaddr;
509509

510-
ret = ttm_tt_populate(bo->bdev, ttm, &ctx);
510+
ret = ttm_bo_populate(bo, &ctx);
511511
if (ret)
512512
return ret;
513513

drivers/gpu/drm/ttm/ttm_bo_vm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
224224
};
225225

226226
ttm = bo->ttm;
227-
err = ttm_tt_populate(bdev, bo->ttm, &ctx);
227+
err = ttm_bo_populate(bo, &ctx);
228228
if (err) {
229229
if (err == -EINTR || err == -ERESTARTSYS ||
230230
err == -EAGAIN)

drivers/gpu/drm/ttm/ttm_device.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *func
216216

217217
bdev->vma_manager = vma_manager;
218218
spin_lock_init(&bdev->lru_lock);
219-
INIT_LIST_HEAD(&bdev->pinned);
219+
INIT_LIST_HEAD(&bdev->unevictable);
220220
bdev->dev_mapping = mapping;
221221
mutex_lock(&ttm_global_mutex);
222222
list_add_tail(&bdev->device_list, &glob->device_list);
@@ -283,7 +283,7 @@ void ttm_device_clear_dma_mappings(struct ttm_device *bdev)
283283
struct ttm_resource_manager *man;
284284
unsigned int i, j;
285285

286-
ttm_device_clear_lru_dma_mappings(bdev, &bdev->pinned);
286+
ttm_device_clear_lru_dma_mappings(bdev, &bdev->unevictable);
287287

288288
for (i = TTM_PL_SYSTEM; i < TTM_NUM_MEM_TYPES; ++i) {
289289
man = ttm_manager_type(bdev, i);

drivers/gpu/drm/ttm/ttm_resource.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <drm/ttm/ttm_bo.h>
3131
#include <drm/ttm/ttm_placement.h>
3232
#include <drm/ttm/ttm_resource.h>
33+
#include <drm/ttm/ttm_tt.h>
3334

3435
#include <drm/drm_util.h>
3536

@@ -235,19 +236,34 @@ static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
235236
}
236237
}
237238

239+
static bool ttm_resource_is_swapped(struct ttm_resource *res, struct ttm_buffer_object *bo)
240+
{
241+
/*
242+
* Take care when creating a new resource for a bo, that it is not considered
243+
* swapped if it's not the current resource for the bo and is thus logically
244+
* associated with the ttm_tt. Think a VRAM resource created to move a
245+
* swapped-out bo to VRAM.
246+
*/
247+
if (bo->resource != res || !bo->ttm)
248+
return false;
249+
250+
dma_resv_assert_held(bo->base.resv);
251+
return ttm_tt_is_swapped(bo->ttm);
252+
}
253+
238254
/* Add the resource to a bulk move if the BO is configured for it */
239255
void ttm_resource_add_bulk_move(struct ttm_resource *res,
240256
struct ttm_buffer_object *bo)
241257
{
242-
if (bo->bulk_move && !bo->pin_count)
258+
if (bo->bulk_move && !bo->pin_count && !ttm_resource_is_swapped(res, bo))
243259
ttm_lru_bulk_move_add(bo->bulk_move, res);
244260
}
245261

246262
/* Remove the resource from a bulk move if the BO is configured for it */
247263
void ttm_resource_del_bulk_move(struct ttm_resource *res,
248264
struct ttm_buffer_object *bo)
249265
{
250-
if (bo->bulk_move && !bo->pin_count)
266+
if (bo->bulk_move && !bo->pin_count && !ttm_resource_is_swapped(res, bo))
251267
ttm_lru_bulk_move_del(bo->bulk_move, res);
252268
}
253269

@@ -259,8 +275,8 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
259275

260276
lockdep_assert_held(&bo->bdev->lru_lock);
261277

262-
if (bo->pin_count) {
263-
list_move_tail(&res->lru.link, &bdev->pinned);
278+
if (bo->pin_count || ttm_resource_is_swapped(res, bo)) {
279+
list_move_tail(&res->lru.link, &bdev->unevictable);
264280

265281
} else if (bo->bulk_move) {
266282
struct ttm_lru_bulk_move_pos *pos =
@@ -301,8 +317,8 @@ void ttm_resource_init(struct ttm_buffer_object *bo,
301317

302318
man = ttm_manager_type(bo->bdev, place->mem_type);
303319
spin_lock(&bo->bdev->lru_lock);
304-
if (bo->pin_count)
305-
list_add_tail(&res->lru.link, &bo->bdev->pinned);
320+
if (bo->pin_count || ttm_resource_is_swapped(res, bo))
321+
list_add_tail(&res->lru.link, &bo->bdev->unevictable);
306322
else
307323
list_add_tail(&res->lru.link, &man->lru[bo->priority]);
308324
man->usage += res->size;

0 commit comments

Comments
 (0)