From: Lang Yu <lang...@amd.com>

[ Upstream commit 5daff15cd013422bc6d1efcfe82b586800025384 ]

Root PD BO should be reserved before unmap and remove
a bo_va from VM otherwise lockdep will complain.

v2: check fpriv->csa_va is not NULL instead of amdgpu_mcbp (christian)

[14616.936827] WARNING: CPU: 6 PID: 1711 at 
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1762 amdgpu_vm_bo_del+0x399/0x3f0 
[amdgpu]
[14616.937096] Call Trace:
[14616.937097]  <TASK>
[14616.937102]  amdgpu_driver_postclose_kms+0x249/0x2f0 [amdgpu]
[14616.937187]  drm_file_free+0x1d6/0x300 [drm]
[14616.937207]  drm_close_helper.isra.0+0x62/0x70 [drm]
[14616.937220]  drm_release+0x5e/0x100 [drm]
[14616.937234]  __fput+0x9f/0x280
[14616.937239]  ____fput+0xe/0x20
[14616.937241]  task_work_run+0x61/0x90
[14616.937246]  exit_to_user_mode_prepare+0x215/0x220
[14616.937251]  syscall_exit_to_user_mode+0x2a/0x60
[14616.937254]  do_syscall_64+0x48/0x90
[14616.937257]  entry_SYSCALL_64_after_hwframe+0x63/0xcd

Signed-off-by: Lang Yu <lang...@amd.com>
Acked-by: Christian König <christian.koe...@amd.com>
Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 38 +++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_csa.h |  3 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 10 +++----
 3 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
index c6d4d41c4393e..23d054526e7c7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
@@ -106,3 +106,41 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, 
struct amdgpu_vm *vm,
        ttm_eu_backoff_reservation(&ticket, &list);
        return 0;
 }
+
+int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+                           struct amdgpu_bo *bo, struct amdgpu_bo_va *bo_va,
+                           uint64_t csa_addr)
+{
+       struct ww_acquire_ctx ticket;
+       struct list_head list;
+       struct amdgpu_bo_list_entry pd;
+       struct ttm_validate_buffer csa_tv;
+       int r;
+
+       INIT_LIST_HEAD(&list);
+       INIT_LIST_HEAD(&csa_tv.head);
+       csa_tv.bo = &bo->tbo;
+       csa_tv.num_shared = 1;
+
+       list_add(&csa_tv.head, &list);
+       amdgpu_vm_get_pd_bo(vm, &list, &pd);
+
+       r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
+       if (r) {
+               DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r);
+               return r;
+       }
+
+       r = amdgpu_vm_bo_unmap(adev, bo_va, csa_addr);
+       if (r) {
+               DRM_ERROR("failed to do bo_unmap on static CSA, err=%d\n", r);
+               ttm_eu_backoff_reservation(&ticket, &list);
+               return r;
+       }
+
+       amdgpu_vm_bo_del(adev, bo_va);
+
+       ttm_eu_backoff_reservation(&ticket, &list);
+
+       return 0;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.h
index 524b4437a0217..7dfc1f2012ebf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.h
@@ -34,6 +34,9 @@ int amdgpu_allocate_static_csa(struct amdgpu_device *adev, 
struct amdgpu_bo **bo
 int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                          struct amdgpu_bo *bo, struct amdgpu_bo_va **bo_va,
                          uint64_t csa_addr, uint32_t size);
+int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+                           struct amdgpu_bo *bo, struct amdgpu_bo_va *bo_va,
+                           uint64_t csa_addr);
 void amdgpu_free_static_csa(struct amdgpu_bo **bo);
 
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 0efb38539d70c..724e80c192973 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -1284,12 +1284,12 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
        if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE) != NULL)
                amdgpu_vce_free_handles(adev, file_priv);
 
-       if (amdgpu_mcbp) {
-               /* TODO: how to handle reserve failure */
-               BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, true));
-               amdgpu_vm_bo_del(adev, fpriv->csa_va);
+       if (fpriv->csa_va) {
+               uint64_t csa_addr = amdgpu_csa_vaddr(adev) & 
AMDGPU_GMC_HOLE_MASK;
+
+               WARN_ON(amdgpu_unmap_static_csa(adev, &fpriv->vm, 
adev->virt.csa_obj,
+                                               fpriv->csa_va, csa_addr));
                fpriv->csa_va = NULL;
-               amdgpu_bo_unreserve(adev->virt.csa_obj);
        }
 
        pasid = fpriv->vm.pasid;
-- 
2.39.2

Reply via email to