diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 62 |
1 files 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 | |||
@@ -938,6 +938,35 @@ error_free_pt: | |||
938 | } | 938 | } |
939 | 939 | ||
940 | /** | 940 | /** |
941 | * amdgpu_vm_free_pts - free PD/PT levels | ||
942 | * | ||
943 | * @adev: amdgpu device structure | ||
944 | * @parent: PD/PT starting level to free | ||
945 | * @level: level of parent structure | ||
946 | * | ||
947 | * Free the page directory or page table level and all sub levels. | ||
948 | */ | ||
949 | static void amdgpu_vm_free_pts(struct amdgpu_device *adev, | ||
950 | struct amdgpu_vm *vm) | ||
951 | { | ||
952 | struct amdgpu_vm_pt_cursor cursor; | ||
953 | struct amdgpu_vm_pt *entry; | ||
954 | |||
955 | for_each_amdgpu_vm_pt_dfs_safe(adev, vm, cursor, entry) { | ||
956 | |||
957 | if (entry->base.bo) { | ||
958 | list_del(&entry->base.bo_list); | ||
959 | list_del(&entry->base.vm_status); | ||
960 | amdgpu_bo_unref(&entry->base.bo->shadow); | ||
961 | amdgpu_bo_unref(&entry->base.bo); | ||
962 | } | ||
963 | kvfree(entry->entries); | ||
964 | } | ||
965 | |||
966 | BUG_ON(vm->root.base.bo); | ||
967 | } | ||
968 | |||
969 | /** | ||
941 | * amdgpu_vm_check_compute_bug - check whether asic has compute vm bug | 970 | * amdgpu_vm_check_compute_bug - check whether asic has compute vm bug |
942 | * | 971 | * |
943 | * @adev: amdgpu_device pointer | 972 | * @adev: amdgpu_device pointer |
@@ -3148,36 +3177,6 @@ void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
3148 | } | 3177 | } |
3149 | 3178 | ||
3150 | /** | 3179 | /** |
3151 | * amdgpu_vm_free_levels - free PD/PT levels | ||
3152 | * | ||
3153 | * @adev: amdgpu device structure | ||
3154 | * @parent: PD/PT starting level to free | ||
3155 | * @level: level of parent structure | ||
3156 | * | ||
3157 | * Free the page directory or page table level and all sub levels. | ||
3158 | */ | ||
3159 | static void amdgpu_vm_free_levels(struct amdgpu_device *adev, | ||
3160 | struct amdgpu_vm_pt *parent, | ||
3161 | unsigned level) | ||
3162 | { | ||
3163 | unsigned i, num_entries = amdgpu_vm_num_entries(adev, level); | ||
3164 | |||
3165 | if (parent->base.bo) { | ||
3166 | list_del(&parent->base.bo_list); | ||
3167 | list_del(&parent->base.vm_status); | ||
3168 | amdgpu_bo_unref(&parent->base.bo->shadow); | ||
3169 | amdgpu_bo_unref(&parent->base.bo); | ||
3170 | } | ||
3171 | |||
3172 | if (parent->entries) | ||
3173 | for (i = 0; i < num_entries; i++) | ||
3174 | amdgpu_vm_free_levels(adev, &parent->entries[i], | ||
3175 | level + 1); | ||
3176 | |||
3177 | kvfree(parent->entries); | ||
3178 | } | ||
3179 | |||
3180 | /** | ||
3181 | * amdgpu_vm_fini - tear down a vm instance | 3180 | * amdgpu_vm_fini - tear down a vm instance |
3182 | * | 3181 | * |
3183 | * @adev: amdgpu_device pointer | 3182 | * @adev: amdgpu_device pointer |
@@ -3237,8 +3236,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
3237 | if (r) { | 3236 | if (r) { |
3238 | dev_err(adev->dev, "Leaking page tables because BO reservation failed\n"); | 3237 | dev_err(adev->dev, "Leaking page tables because BO reservation failed\n"); |
3239 | } else { | 3238 | } else { |
3240 | amdgpu_vm_free_levels(adev, &vm->root, | 3239 | amdgpu_vm_free_pts(adev, vm); |
3241 | adev->vm_manager.root_level); | ||
3242 | amdgpu_bo_unreserve(root); | 3240 | amdgpu_bo_unreserve(root); |
3243 | } | 3241 | } |
3244 | amdgpu_bo_unref(&root); | 3242 | amdgpu_bo_unref(&root); |