From a133b900c05d632e06cc7d5a9136473e4f07f846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 6 Sep 2018 15:35:13 +0200 Subject: [PATCH 5409/5725] drm/amdgpu: use dfs iterator to free PDs/PTs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows us to free all PDs/PTs without recursion. Change-Id: I4d40cc769b5bf29e619fe2886ee785a62e72f961 Signed-off-by: Christian König Reviewed-by: Felix Kuehling Reviewed-by: Junwei Zhang Reviewed-by: Huang Rui Signed-off-by: Raveendra Talabattula --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 62 ++++++++++++++++------------------ 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 7499956..f90fced 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -867,6 +867,35 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, } /** + * amdgpu_vm_free_pts - free PD/PT levels + * + * @adev: amdgpu device structure + * @parent: PD/PT starting level to free + * @level: level of parent structure + * + * Free the page directory or page table level and all sub levels. + */ +static void amdgpu_vm_free_pts(struct amdgpu_device *adev, + struct amdgpu_vm *vm) +{ + struct amdgpu_vm_pt_cursor cursor; + struct amdgpu_vm_pt *entry; + + for_each_amdgpu_vm_pt_dfs_safe(adev, vm, cursor, entry) { + + if (entry->base.bo) { + list_del(&entry->base.bo_list); + list_del(&entry->base.vm_status); + amdgpu_bo_unref(&entry->base.bo->shadow); + amdgpu_bo_unref(&entry->base.bo); + } + kvfree(entry->entries); + } + + BUG_ON(vm->root.base.bo); +} + +/** * amdgpu_vm_check_compute_bug - check whether asic has compute vm bug * * @adev: amdgpu_device pointer @@ -3091,36 +3120,6 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns } /** - * amdgpu_vm_free_levels - free PD/PT levels - * - * @adev: amdgpu device structure - * @parent: PD/PT starting level to free - * @level: level of parent structure - * - * Free the page directory or page table level and all sub levels. - */ -static void amdgpu_vm_free_levels(struct amdgpu_device *adev, - struct amdgpu_vm_pt *parent, - unsigned level) -{ - unsigned i, num_entries = amdgpu_vm_num_entries(adev, level); - - if (parent->base.bo) { - list_del(&parent->base.bo_list); - list_del(&parent->base.vm_status); - amdgpu_bo_unref(&parent->base.bo->shadow); - amdgpu_bo_unref(&parent->base.bo); - } - - if (parent->entries) - for (i = 0; i < num_entries; i++) - amdgpu_vm_free_levels(adev, &parent->entries[i], - level + 1); - - kvfree(parent->entries); -} - -/** * amdgpu_vm_fini - tear down a vm instance * * @adev: amdgpu_device pointer @@ -3179,8 +3178,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) if (r) { dev_err(adev->dev, "Leaking page tables because BO reservation failed\n"); } else { - amdgpu_vm_free_levels(adev, &vm->root, - adev->vm_manager.root_level); + amdgpu_vm_free_pts(adev, vm); amdgpu_bo_unreserve(root); } amdgpu_bo_unref(&root); -- 2.7.4