summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/ttm/ttm_bo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo.c')
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c91
1 files changed, 90 insertions, 1 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 7c484729f9b2..b2a33bf1ef10 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -214,15 +214,104 @@ void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo)
}
EXPORT_SYMBOL(ttm_bo_del_sub_from_lru);
-void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo)
+static void ttm_bo_bulk_move_set_pos(struct ttm_lru_bulk_move_pos *pos,
+ struct ttm_buffer_object *bo)
+{
+ if (!pos->first)
+ pos->first = bo;
+ pos->last = bo;
+}
+
+void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo,
+ struct ttm_lru_bulk_move *bulk)
{
reservation_object_assert_held(bo->resv);
ttm_bo_del_from_lru(bo);
ttm_bo_add_to_lru(bo);
+
+ if (bulk && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
+ switch (bo->mem.mem_type) {
+ case TTM_PL_TT:
+ ttm_bo_bulk_move_set_pos(&bulk->tt[bo->priority], bo);
+ break;
+
+ case TTM_PL_VRAM:
+ ttm_bo_bulk_move_set_pos(&bulk->vram[bo->priority], bo);
+ break;
+ }
+ if (bo->ttm && !(bo->ttm->page_flags &
+ (TTM_PAGE_FLAG_SG | TTM_PAGE_FLAG_SWAPPED)))
+ ttm_bo_bulk_move_set_pos(&bulk->swap[bo->priority], bo);
+ }
}
EXPORT_SYMBOL(ttm_bo_move_to_lru_tail);
+static void ttm_list_move_bulk_tail(struct list_head *list,
+ struct list_head *first,
+ struct list_head *last)
+{
+ first->prev->next = last->next;
+ last->next->prev = first->prev;
+
+ list->prev->next = first;
+ first->prev = list->prev;
+
+ last->next = list;
+ list->prev = last;
+}
+
+void ttm_bo_bulk_move_lru_tail(struct ttm_lru_bulk_move *bulk)
+{
+ unsigned i;
+
+ for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
+ struct ttm_lru_bulk_move_pos *pos = &bulk->tt[i];
+ struct ttm_mem_type_manager *man;
+
+ if (!pos->first)
+ continue;
+
+ reservation_object_assert_held(pos->first->resv);
+ reservation_object_assert_held(pos->last->resv);
+
+ man = &pos->first->bdev->man[TTM_PL_TT];
+ ttm_list_move_bulk_tail(&man->lru[i], &pos->first->lru,
+ &pos->last->lru);
+ }
+
+ for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
+ struct ttm_lru_bulk_move_pos *pos = &bulk->vram[i];
+ struct ttm_mem_type_manager *man;
+
+ if (!pos->first)
+ continue;
+
+ reservation_object_assert_held(pos->first->resv);
+ reservation_object_assert_held(pos->last->resv);
+
+ man = &pos->first->bdev->man[TTM_PL_VRAM];
+ ttm_list_move_bulk_tail(&man->lru[i], &pos->first->lru,
+ &pos->last->lru);
+ }
+
+ for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
+ struct ttm_lru_bulk_move_pos *pos = &bulk->swap[i];
+ struct list_head *lru;
+
+ if (!pos->first)
+ continue;
+
+ reservation_object_assert_held(pos->first->resv);
+ reservation_object_assert_held(pos->last->resv);
+
+ lru = &pos->first->bdev->glob->swap_lru[i];
+ ttm_list_move_bulk_tail(lru, &pos->first->swap,
+ &pos->last->swap);
+ }
+}
+EXPORT_SYMBOL(ttm_bo_bulk_move_lru_tail);
+
static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
struct ttm_mem_reg *mem, bool evict,
struct ttm_operation_ctx *ctx)