The first-level trap mapping is a property of a GPU virtual address
space, not of a queue type. User queues and kernel queues executing in
the same GPUVM read the same TMA, so both paths must not carry separate
trap allocations.

Move ownership of the trap object to struct amdgpu_vm and create it
during VM initialization. Access the trap object directly through the
GPUVM instead of keeping a duplicate fpriv alias. This also establishes
the trap mapping before a GPUVM can be used by any queue type, which
allows the gfxhub setup code in the following patch to enable TRAP_EN
without a deferred allocation.

The first-level ISA binary is identical across VMs for the same hardware
generation. It is copied once into adev->trap_info->isa_bo at device
init and mapped into each GPUVM at vm_init rather than duplicated
per-VM.

Suggested-by: Christian König <[email protected]>
Suggested-by: Alex Deucher <[email protected]>
Cc: Felix Kuehling <[email protected]>
Cc: Lancelot Six <[email protected]>
Cc: James Zhu <[email protected]>
Cc: Lijo Lazar <[email protected]>
Cc: Samuel Pitoiset <[email protected]>
Cc: Natalie Vock <[email protected]>
Cc: Timur Kristóf <[email protected]>
Cc: Pierre-Eric Pelloux-Prayer <[email protected]>
Signed-off-by: Srinivasan Shanmugam <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  9 +--------
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     | 20 ++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h     |  4 ++++
 drivers/gpu/drm/amd/amdgpu/mes_userqueue.c |  7 +++----
 5 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index e3763c197138..c228f3c7ac4d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -417,7 +417,6 @@ struct amdgpu_fpriv {
        struct xarray           bo_list_handles;
        struct amdgpu_ctx_mgr   ctx_mgr;
        struct amdgpu_userq_mgr userq_mgr;
-       struct amdgpu_trap_obj *trap_obj;
 
        /* Eviction fence infra */
        struct amdgpu_eviction_fence_mgr evf_mgr;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 559c9222fc48..1e23a68b5c5b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -1499,7 +1499,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
                int num_xcc, r;
 
                fpriv = (struct amdgpu_fpriv *)filp->driver_priv;
-               if (!amdgpu_trap_is_enabled(adev) || !fpriv->trap_obj)
+               if (!amdgpu_trap_is_enabled(adev) || !fpriv->vm.trap_obj)
                        return -EOPNOTSUPP;
                num_xcc = amdgpu_xcp_get_num_xcc(adev->xcp_mgr, fpriv->xcp_id);
                cwsr_info.ctl_stack_size =
@@ -1641,12 +1641,6 @@ int amdgpu_driver_open_kms(struct drm_device *dev, 
struct drm_file *file_priv)
 
        amdgpu_evf_mgr_init(&fpriv->evf_mgr);
 
-       if (amdgpu_trap_is_enabled(adev)) {
-               r = amdgpu_trap_alloc(adev, &fpriv->vm, &fpriv->trap_obj);
-               if (r)
-                       dev_dbg(adev->dev, "trap handler not enabled");
-       }
-
        amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
 
        file_priv->driver_priv = fpriv;
@@ -1716,7 +1710,6 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
        }
 
        amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
-       amdgpu_trap_free(adev, &fpriv->vm, &fpriv->userq_mgr, &fpriv->trap_obj);
 
        if (pasid)
                amdgpu_pasid_free_delayed(pd->tbo.base.resv, pasid);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 930b744c5f5f..99a9605f8e15 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -44,6 +44,7 @@
 #include "amdgpu_dma_buf.h"
 #include "amdgpu_res_cursor.h"
 #include "kfd_svm.h"
+#include "amdgpu_trap.h"
 
 /**
  * DOC: GPUVM
@@ -2646,8 +2647,18 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
        amdgpu_bo_unreserve(vm->root.bo);
        amdgpu_bo_unref(&root_bo);
 
+       if (amdgpu_trap_is_enabled(adev)) {
+               r = amdgpu_trap_alloc(adev, vm, &vm->trap_obj);
+               if (r)
+                       goto error_fini_vm;
+       }
+
        return 0;
 
+error_fini_vm:
+       amdgpu_vm_fini(adev, vm);
+       return r;
+
 error_free_root:
        amdgpu_vm_pt_free_root(adev, vm);
        amdgpu_bo_unreserve(vm->root.bo);
@@ -2753,6 +2764,15 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct 
amdgpu_vm *vm)
 
        amdgpu_amdkfd_gpuvm_destroy_cb(adev, vm);
 
+       /*
+        * Free trap state before reserving root. amdgpu_trap_free()
+        * uses drm_exec to lock the page directory internally; calling
+        * it after amdgpu_bo_reserve(root) would deadlock on the same
+        * ww_mutex.
+        */
+       if (vm->trap_obj)
+               amdgpu_trap_free(adev, vm, NULL, &vm->trap_obj);
+
        root = amdgpu_bo_ref(vm->root.bo);
        amdgpu_bo_reserve(root, true);
        dma_fence_wait(vm->last_unlocked, false);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index dd825e179979..bbf4aa96e15a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -43,6 +43,7 @@ struct amdgpu_bo_va;
 struct amdgpu_job;
 struct amdgpu_bo_list_entry;
 struct amdgpu_bo_vm;
+struct amdgpu_trap_obj;
 
 /*
  * GPUVM handling
@@ -488,6 +489,9 @@ struct amdgpu_vm {
 
        /* cached fault info */
        struct amdgpu_vm_fault_info fault_info;
+
+       /* First-level trap state shared by all queue paths using this GPUVM. */
+       struct amdgpu_trap_obj *trap_obj;
 };
 
 struct amdgpu_vm_manager {
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c 
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index 2150973b947d..1cce81914be9 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -138,7 +138,6 @@ static int convert_to_mes_priority(int priority)
 static int mes_userq_map(struct amdgpu_usermode_queue *queue)
 {
        struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
-       struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr);
        struct amdgpu_device *adev = uq_mgr->adev;
        struct amdgpu_userq_obj *ctx = &queue->fw_obj;
        struct amdgpu_mqd_prop *userq_props = queue->userq_prop;
@@ -172,9 +171,9 @@ static int mes_userq_map(struct amdgpu_usermode_queue 
*queue)
                queue_input.is_kfd_process = 1;
                queue_input.is_aql_queue = 1;
        }
-       if (fpriv->trap_obj) {
-               queue_input.tba_addr = fpriv->trap_obj->tba_gpu_va_addr;
-               queue_input.tma_addr = fpriv->trap_obj->tma_gpu_va_addr;
+       if (queue->vm->trap_obj) {
+               queue_input.tba_addr = queue->vm->trap_obj->tba_gpu_va_addr;
+               queue_input.tma_addr = queue->vm->trap_obj->tma_gpu_va_addr;
                queue_input.trap_en = !amdgpu_trap_has_dbg_wa(adev);
        }
 
-- 
2.34.1

Reply via email to