From: Yu Huang <[email protected]>
amdgpu_vm_pt_alloc() drops the VM critical section while
allocating a page table. If allocation succeeds but re-entering the
critical section finds that the VM is evicting, the new page-table BO
is returned without being released.
Temporarily leave the failed critical section, release the
unpublished BO and re-enter it so that the caller still owns the
critical section on return and can run the normal cleanup path.
Fixes: 39061e38483a ("drm/amdgpu: rework eviction lock handling into critical
section v2")
Signed-off-by: Yu Huang <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
index 5385f662d0ac..ec7bdec1a3a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
@@ -504,13 +504,17 @@ static int amdgpu_vm_pt_alloc(struct
amdgpu_vm_update_params *p,
r2 = amdgpu_vm_begin_critical(p);
if (r)
return r;
- if (r2)
+ pt_bo = &pt->bo;
+ if (r2) {
+ amdgpu_vm_end_critical(p);
+ amdgpu_bo_unref(&pt_bo);
+ (void)amdgpu_vm_begin_critical(p);
return r2;
+ }
/* Keep a reference to the root directory to avoid
* freeing them up in the wrong order.
*/
- pt_bo = &pt->bo;
pt_bo->parent = amdgpu_bo_ref(cursor->parent->bo);
amdgpu_vm_bo_base_init(entry, p->vm, pt_bo);
r = amdgpu_vm_pt_clear(p->adev, p->vm, pt);
--
2.53.0