When one VM BOs validated move all of them them to the end of the LRU to keep them together. Signed-off-by: Christian König <christian.koenig at amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 82 +++++++++++++++++++++++++++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 3 +- 3 files changed, 78 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index d7d7ce1507ec..f8f2471d8606 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -638,7 +638,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, struct amdgpu_bo_list_entry, tv.head); - r = amdgpu_vm_validate_pt_bos(p->adev, &fpriv->vm, + r = amdgpu_vm_validate_pt_bos(p->adev, p->filp, &fpriv->vm, amdgpu_cs_validate, p); if (r) { DRM_ERROR("amdgpu_vm_validate_pt_bos() failed.\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index a2f8b57838ff..f81d19dae56f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -180,21 +180,80 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, list_add(&entry->tv.head, validated); } +/** + * amdgpu_vm_move_bos - move per VM BOs to the end of the LRU + * + * @id: unused + * @ptr: ptr to the GEM object + * @data: ptr to the VM + * + * Make sure that all per VM BOs are grouped together on their LRU. + */ +static int amdgpu_vm_move_bos(int id, void *ptr, void *data) +{ + struct amdgpu_bo *bo = gem_to_amdgpu_bo(ptr); + struct amdgpu_vm *vm = data; + + if (bo->tbo.resv != vm->root.base.bo->tbo.resv) + return 0; + + ttm_bo_move_to_lru_tail(&bo->tbo); + if (bo->shadow) + ttm_bo_move_to_lru_tail(&bo->shadow->tbo); + + return 0; +} + +/** + * amdgpu_vm_move_levels - move VM PDs/PTs to the end of the LRU + * + * @adev: amdgpu device structure + * @parent: the parent level with page tables + * @level: the current level + * + * Make sure that all per VM PDs/PTs are grouped together on their LRU. + */ +static void amdgpu_vm_move_levels(struct amdgpu_device *adev, + struct amdgpu_vm_pt *parent, + unsigned level) +{ + struct amdgpu_bo *bo = parent->base.bo; + unsigned i, num_entries; + + if (bo) { + if (bo->parent) + ttm_bo_move_to_lru_tail(&bo->tbo); + if (bo->shadow) + ttm_bo_move_to_lru_tail(&bo->shadow->tbo); + } + + if (!parent->entries) + return; + + num_entries = amdgpu_vm_num_entries(adev, level); + for (i = 0; i < num_entries; i++) + amdgpu_vm_move_levels(adev, &parent->entries[i], + level + 1); +} + /** * amdgpu_vm_validate_pt_bos - validate the page table BOs * * @adev: amdgpu device pointer + * @filp: drm file pointer * @vm: vm providing the BOs * @validate: callback to do the validation * @param: parameter for the validation callback * * Validate the page table BOs on command submission if neccessary. */ -int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, +int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct drm_file *filp, + struct amdgpu_vm *vm, int (*validate)(void *p, struct amdgpu_bo *bo), void *param) { struct ttm_bo_global *glob = adev->mman.bdev.glob; + bool validated = false; int r; spin_lock(&vm->status_lock); @@ -213,12 +272,6 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, r = validate(param, bo); if (r) return r; - - spin_lock(&glob->lru_lock); - ttm_bo_move_to_lru_tail(&bo->tbo); - if (bo->shadow) - ttm_bo_move_to_lru_tail(&bo->shadow->tbo); - spin_unlock(&glob->lru_lock); } if (bo->tbo.type == ttm_bo_type_kernel && @@ -228,6 +281,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, return r; } + validated = true; spin_lock(&vm->status_lock); if (bo->tbo.type != ttm_bo_type_kernel) list_move(&bo_base->vm_status, &vm->moved); @@ -236,6 +290,20 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, } spin_unlock(&vm->status_lock); + if (!validated) + return 0; + + spin_lock(&glob->lru_lock); + + spin_lock(&filp->table_lock); + idr_for_each(&filp->object_idr, amdgpu_vm_move_bos, vm); + spin_unlock(&filp->table_lock); + + amdgpu_vm_move_levels(adev, &vm->root, + adev->vm_manager.root_level); + + spin_unlock(&glob->lru_lock); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index fabf44b262be..a43a493f5c08 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -257,7 +257,8 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, struct list_head *validated, struct amdgpu_bo_list_entry *entry); bool amdgpu_vm_ready(struct amdgpu_vm *vm); -int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, +int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct drm_file *filp, + struct amdgpu_vm *vm, int (*callback)(void *p, struct amdgpu_bo *bo), void *param); int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, -- 2.14.1