From 229a37f83454c59a9c8742c811119da4a33d619b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Thu, 6 Sep 2018 15:35:13 +0200 Subject: [PATCH] drm/amdgpu: use dfs iterator to free PDs/PTs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Allows us to free all PDs/PTs without recursion. Signed-off-by: Christian König Reviewed-by: Felix Kuehling Reviewed-by: Junwei Zhang Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- 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 60fa4f455b52..139bd6347fc4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -937,6 +937,35 @@ error_free_pt: return r; } +/** + * 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 * @@ -3147,36 +3176,6 @@ void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm) vm->pasid = 0; } -/** - * 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 * @@ -3237,8 +3236,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.30.2