Change-Id: Iaca5cdaccbc5beeb7a37c0f703cdfc97df4ece4f Signed-off-by: Chunming Zhou <david1.zhou at amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 85 +++++++++++++++++++++++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 3 +- 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index f04fc401327b..b6396230d30e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -82,6 +82,8 @@ struct amdgpu_bo { struct ttm_placement placement; struct ttm_buffer_object tbo; struct ttm_bo_kmap_obj kmap; + struct rb_node node; + u64 index; u64 flags; unsigned pin_count; u64 tiling_flags; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 207f88f38b23..a5d8f511b011 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1279,6 +1279,7 @@ static struct ttm_bo_driver amdgpu_bo_driver = { .invalidate_caches = &amdgpu_invalidate_caches, .init_mem_type = &amdgpu_init_mem_type, .eviction_valuable = amdgpu_ttm_bo_eviction_valuable, + .lru_empty = &amdgpu_vm_lru_empty, .get_evictable_bo = &amdgpu_vm_get_evictable_bo, .add_to_lru = &amdgpu_vm_add_to_lru, .del_from_lru = &amdgpu_vm_del_from_lru, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 27b3fdb6dd46..1a09c07bbf20 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -133,7 +133,7 @@ int amdgpu_vm_lru_init(struct amdgpu_vm_lru *vm_lru, struct amdgpu_device *adev, INIT_LIST_HEAD(&vm_lru->vm_lru_list); for (i = 0; i < TTM_NUM_MEM_TYPES; i++) { for (j = 0; j < TTM_MAX_BO_PRIORITY; j++) { - INIT_LIST_HEAD(&vm_lru->fixed_lru[i][j]); + vm_lru->fixed_lru[i][j] = RB_ROOT; INIT_LIST_HEAD(&vm_lru->dynamic_lru[i][j]); } } @@ -157,6 +157,24 @@ int amdgpu_vm_lru_fini(struct amdgpu_vm_lru *vm_lru, struct amdgpu_device *adev) return 0; } +bool amdgpu_vm_lru_empty(struct ttm_bo_device *bdev, unsigned mem_type) +{ + struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); + struct amdgpu_vm_lru *vm_lru; + int i; + + for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { + list_for_each_entry(vm_lru, &adev->vm_lru_list, vm_lru_list) { + if (!list_empty(&vm_lru->dynamic_lru[mem_type][i])) + return false; + if (!RB_EMPTY_ROOT(&vm_lru->fixed_lru[mem_type][i])) + return false; + } + } + + return true; +} + struct ttm_buffer_object *amdgpu_vm_get_evictable_bo(struct ttm_bo_device *bdev, uint32_t mem_type, const struct ttm_place *place, @@ -165,11 +183,13 @@ struct ttm_buffer_object *amdgpu_vm_get_evictable_bo(struct ttm_bo_device *bdev, { struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); struct ttm_buffer_object *bo = NULL; + struct amdgpu_bo *abo = NULL; struct amdgpu_vm_lru *vm_lru; int i; for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { list_for_each_entry(vm_lru, &adev->vm_lru_list, vm_lru_list) { + struct rb_node *node; list_for_each_entry(bo, &vm_lru->dynamic_lru[mem_type][i], lru) { if (!ttm_bo_evict_swapout_allowable(bo, ctx, locked)) continue; @@ -184,20 +204,22 @@ struct ttm_buffer_object *amdgpu_vm_get_evictable_bo(struct ttm_bo_device *bdev, if (&bo->lru != &vm_lru->dynamic_lru[mem_type][i]) break; bo = NULL; - list_for_each_entry(bo, &vm_lru->fixed_lru[mem_type][i], lru) { - if (!ttm_bo_evict_swapout_allowable(bo, ctx, locked)) + for (node = rb_first(&vm_lru->fixed_lru[mem_type][i]); + node; node = rb_next(node)) { + abo = rb_entry(node, struct amdgpu_bo, node); + bo = &abo->tbo; + if (!ttm_bo_evict_swapout_allowable(bo, ctx, locked)) { + bo = NULL; continue; + } if (place && !bdev->driver->eviction_valuable(bo, place)) { if (locked) reservation_object_unlock(bo->resv); + bo = NULL; continue; } break; } - /* If the inner loop terminated early, we have our candidate */ - if (&bo->lru != &vm_lru->fixed_lru[mem_type][i]) - break; - bo = NULL; } if (bo) break; @@ -207,6 +229,26 @@ struct ttm_buffer_object *amdgpu_vm_get_evictable_bo(struct ttm_bo_device *bdev, } +static void amdgpu_vm_bo_add_to_rb(struct amdgpu_bo *bo, + struct rb_root *root) +{ + struct rb_node **new = &(root->rb_node), *parent = NULL; + + while (*new) { + struct amdgpu_bo *this = + container_of(*new, struct amdgpu_bo, node); + + parent = *new; + if (bo->index < this->index) + new = &((*new)->rb_left); + else + new = &((*new)->rb_right); + } + + rb_link_node(&bo->node, parent, new); + rb_insert_color(&bo->node, root); +} + void amdgpu_vm_add_to_lru(struct ttm_buffer_object *bo) { struct ttm_bo_device *bdev = bo->bdev; @@ -215,7 +257,7 @@ void amdgpu_vm_add_to_lru(struct ttm_buffer_object *bo) if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { if (bo->resv == vm_lru->resv) - list_add_tail(&bo->lru, &vm_lru->fixed_lru[bo->mem.mem_type][bo->priority]); + amdgpu_vm_bo_add_to_rb(abo, &vm_lru->fixed_lru[bo->mem.mem_type][bo->priority]); else list_add_tail(&bo->lru, &vm_lru->dynamic_lru[bo->mem.mem_type][bo->priority]); kref_get(&bo->list_kref); @@ -230,9 +272,36 @@ void amdgpu_vm_add_to_lru(struct ttm_buffer_object *bo) } +static struct amdgpu_bo *amdgpu_vm_bo_rb_find(struct rb_root *root, u64 index) +{ + struct rb_node *node = root->rb_node; + + while (node) { + struct amdgpu_bo *bo = + container_of(node, struct amdgpu_bo, node); + + if (index < bo->index) + node = node->rb_left; + else if (index > bo->index) + node = node->rb_right; + else + return bo; + } + + return NULL; +} + void amdgpu_vm_del_from_lru(struct ttm_buffer_object *bo) { + struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); + struct amdgpu_vm_lru *vm_lru = abo->vm_lru; + if (amdgpu_vm_bo_rb_find(&vm_lru->fixed_lru[bo->mem.mem_type][bo->priority], + abo->index)) { + rb_erase(&abo->node, + &vm_lru->fixed_lru[abo->tbo.mem.mem_type][abo->tbo.priority]); + kref_put(&abo->tbo.list_kref, ttm_bo_ref_bug); + } } void amdgpu_vm_move_to_lru_tail(struct ttm_buffer_object *bo) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 66ee902614a2..84400673d710 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -138,7 +138,7 @@ enum amdgpu_vm_level { struct amdgpu_vm_lru { struct list_head vm_lru_list; - struct list_head fixed_lru[TTM_NUM_MEM_TYPES][TTM_MAX_BO_PRIORITY]; + struct rb_root fixed_lru[TTM_NUM_MEM_TYPES][TTM_MAX_BO_PRIORITY]; struct list_head dynamic_lru[TTM_NUM_MEM_TYPES][TTM_MAX_BO_PRIORITY]; struct reservation_object *resv; }; @@ -269,6 +269,7 @@ int amdgpu_vm_lru_init(struct amdgpu_vm_lru *vm_lru, struct amdgpu_device *adev, struct reservation_object *resv); int amdgpu_vm_lru_fini(struct amdgpu_vm_lru *vm_lru, struct amdgpu_device *adev); +bool amdgpu_vm_lru_empty(struct ttm_bo_device *bdev, unsigned mem_type); struct ttm_buffer_object *amdgpu_vm_get_evictable_bo(struct ttm_bo_device *bdev, uint32_t mem_type, -- 2.14.1