Commit 229a37f8 authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: use dfs iterator to free PDs/PTs

Allows us to free all PDs/PTs without recursion.
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: default avatarJunwei Zhang <Jerry.Zhang@amd.com>
Reviewed-by: default avatarHuang Rui <ray.huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent d72a6887
...@@ -937,6 +937,35 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, ...@@ -937,6 +937,35 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
return r; 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 * 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) ...@@ -3147,36 +3176,6 @@ void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
vm->pasid = 0; 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 * amdgpu_vm_fini - tear down a vm instance
* *
...@@ -3237,8 +3236,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) ...@@ -3237,8 +3236,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
if (r) { if (r) {
dev_err(adev->dev, "Leaking page tables because BO reservation failed\n"); dev_err(adev->dev, "Leaking page tables because BO reservation failed\n");
} else { } else {
amdgpu_vm_free_levels(adev, &vm->root, amdgpu_vm_free_pts(adev, vm);
adev->vm_manager.root_level);
amdgpu_bo_unreserve(root); amdgpu_bo_unreserve(root);
} }
amdgpu_bo_unref(&root); amdgpu_bo_unref(&root);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment