On 07/02/2023 08:20, Christian König wrote:


Am 03.02.23 um 22:54 schrieb Shashank Sharma:
From: Shashank Sharma <contactshashanksha...@gmail.com>

This patch adds new fptrs to prepare the usermode queue to be
mapped or unmapped into the HW. After this mapping, the queue
will be ready to accept the workload.

V1: Addressed review comments from Alex on the RFC patch series
     - Map/Unmap should be IP specific.

Cc: Alex Deucher <alexander.deuc...@amd.com>
Cc: Christian Koenig <christian.koe...@amd.com>
Signed-off-by: Shashank Sharma <shashank.sha...@amd.com>
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 57 +++++++++++++++++++
  .../amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c | 47 +++++++++++++++
  .../gpu/drm/amd/include/amdgpu_userqueue.h    |  2 +
  3 files changed, 106 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
index 18281b3a51f1..cbfe2608c040 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
@@ -42,6 +42,53 @@ static struct amdgpu_usermode_queue
      return idr_find(&uq_mgr->userq_idr, qid);
  }
  +static void
+amdgpu_userqueue_unmap(struct amdgpu_userq_mgr *uq_mgr,
+                     struct amdgpu_usermode_queue *queue)
+{
+    int r;
+    struct amdgpu_device *adev = uq_mgr->adev;
+    struct mes_remove_queue_input remove_request;
+
+    uq_mgr->userq_mqd_funcs->prepare_unmap(uq_mgr, queue, (void *)&remove_request);
+
+    amdgpu_mes_lock(&adev->mes);
+    r = adev->mes.funcs->remove_hw_queue(&adev->mes, &remove_request);
+    amdgpu_mes_unlock(&adev->mes);
+    if (r) {
+        DRM_ERROR("Failed to unmap usermode queue %d\n", queue->queue_id);
+        return;
+    }
+
+    DRM_DEBUG_DRIVER("Usermode queue %d unmapped\n", queue->queue_id);
+}
+
+static int
+amdgpu_userqueue_map(struct amdgpu_userq_mgr *uq_mgr,
+                     struct amdgpu_usermode_queue *queue)
+{
+    int r;
+    struct amdgpu_device *adev = uq_mgr->adev;
+    struct mes_add_queue_input add_request;
+
+    r = uq_mgr->userq_mqd_funcs->prepare_map(uq_mgr, queue, (void *)&add_request);
+    if (r) {
+        DRM_ERROR("Failed to map userqueue\n");
+        return r;
+    }
+
+    amdgpu_mes_lock(&adev->mes);
+    r = adev->mes.funcs->add_hw_queue(&adev->mes, &add_request);
+    amdgpu_mes_unlock(&adev->mes);
+    if (r) {
+        DRM_ERROR("Failed to map queue in HW, err (%d)\n", r);
+        return r;
+    }
+
+    DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", queue->queue_id);
+    return 0;
+}
+
  static void
  amdgpu_userqueue_destroy_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
                                     struct amdgpu_usermode_queue *queue) @@ -170,12 +217,21 @@ static int amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq
          goto free_mqd;
      }
  +    r = amdgpu_userqueue_map(uq_mgr, queue);
+    if (r) {
+        DRM_ERROR("Failed to map userqueue\n");
+        goto free_ctx;
+    }
+
      list_add_tail(&queue->userq_node, &uq_mgr->userq_list);
      args->out.q_id = queue->queue_id;
      args->out.flags = 0;
      mutex_unlock(&uq_mgr->userq_mutex);
      return 0;
  +free_ctx:
+    amdgpu_userqueue_destroy_ctx_space(uq_mgr, queue);
+
  free_mqd:
      amdgpu_userqueue_destroy_mqd(uq_mgr, queue);
  @@ -201,6 +257,7 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
      }
        mutex_lock(&uq_mgr->userq_mutex);
+    amdgpu_userqueue_unmap(uq_mgr, queue);
      amdgpu_userqueue_destroy_ctx_space(uq_mgr, queue);
      amdgpu_userqueue_destroy_mqd(uq_mgr, queue);
      amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c
index 687f90a587e3..d317bb600fd9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c
@@ -24,6 +24,7 @@
  #include "amdgpu_userqueue.h"
  #include "v11_structs.h"
  #include "amdgpu_mes.h"
+#include "mes_api_def.h"
  #include "gc/gc_11_0_0_offset.h"
  #include "gc/gc_11_0_0_sh_mask.h"
  @@ -239,6 +240,50 @@ static void amdgpu_userq_gfx_v11_ctx_destroy(struct amdgpu_userq_mgr *uq_mgr,
                            &pctx->cpu_ptr);
  }
  +static int
+amdgpu_userq_gfx_v11_prepare_map(struct amdgpu_userq_mgr *uq_mgr,
+                                 struct amdgpu_usermode_queue *queue,
+                                 void *q_input)
+{
+    struct amdgpu_device *adev = uq_mgr->adev;
+    struct mes_add_queue_input *queue_input = q_input;
+
+    memset(queue_input, 0x0, sizeof(struct mes_add_queue_input));
+
+    queue_input->process_va_start = 0;
+    queue_input->process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT;
+    queue_input->process_quantum = 100000; /* 10ms */
+    queue_input->gang_quantum = 10000; /* 1ms */
+    queue_input->paging = false;
+
+    queue_input->gang_context_addr = queue->gang_ctx.gpu_addr;
+    queue_input->process_context_addr = queue->proc_ctx.gpu_addr;
+    queue_input->inprocess_gang_priority = AMDGPU_MES_PRIORITY_LEVEL_NORMAL; +    queue_input->gang_global_priority_level = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
+
+    queue_input->process_id = queue->pasid;
+    queue_input->queue_type = queue->queue_type;
+    queue_input->mqd_addr = queue->mqd_gpu_addr;

+    queue_input->wptr_addr = queue->wptr_gpu_addr;
+    queue_input->wptr_mc_addr = queue->wptr_gpu_addr << AMDGPU_GPU_PAGE_SHIFT;

Well that here doesn't make sense at all.

Yes, please ignore this, it was based on old interpretation of wptr_mc_addr. We just prepared a separate patch to map WPTR in GART,

and then calculate the wptr_mc_addr from it, so this line will be removed and that calculation will replace it.

- Shashank


Christian.

+    queue_input->queue_size = queue->queue_size >> 2;
+    queue_input->doorbell_offset = queue->doorbell_index;
+    queue_input->page_table_base_addr = amdgpu_gmc_pd_addr(queue->vm->root.bo);
+    return 0;
+}
+
+static void
+amdgpu_userq_gfx_v11_prepare_unmap(struct amdgpu_userq_mgr *uq_mgr,
+                                   struct amdgpu_usermode_queue *queue,
+                                   void *q_input)
+{
+    struct mes_remove_queue_input *queue_input = q_input;
+
+    memset(queue_input, 0x0, sizeof(struct mes_remove_queue_input));
+    queue_input->doorbell_offset = queue->doorbell_index;
+    queue_input->gang_context_addr = queue->gang_ctx.gpu_addr;
+}
+
  static int amdgpu_userq_gfx_v11_mqd_size(struct amdgpu_userq_mgr *uq_mgr)
  {
      return sizeof(struct v11_gfx_mqd);
@@ -250,4 +295,6 @@ const struct amdgpu_userq_mqd_funcs userq_gfx_v11_mqd_funcs = {
      .mqd_destroy = amdgpu_userq_gfx_v11_mqd_destroy,
      .ctx_create = amdgpu_userq_gfx_v11_ctx_create,
      .ctx_destroy = amdgpu_userq_gfx_v11_ctx_destroy,
+    .prepare_map = amdgpu_userq_gfx_v11_prepare_map,
+    .prepare_unmap = amdgpu_userq_gfx_v11_prepare_unmap,
  };
diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
index 3adcd31618f7..202fac237501 100644
--- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
+++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
@@ -82,6 +82,8 @@ struct amdgpu_userq_mqd_funcs {
      void (*mqd_destroy)(struct amdgpu_userq_mgr *, struct amdgpu_usermode_queue *);       int (*ctx_create)(struct amdgpu_userq_mgr *, struct amdgpu_usermode_queue *);       void (*ctx_destroy)(struct amdgpu_userq_mgr *, struct amdgpu_usermode_queue *); +    int (*prepare_map)(struct amdgpu_userq_mgr *, struct amdgpu_usermode_queue *, void *); +    void (*prepare_unmap)(struct amdgpu_userq_mgr *, struct amdgpu_usermode_queue *, void *);
  };
    int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev);

Reply via email to