AMD General

One inline comment. With that fixed, the series is

Reviewed-by: Michael Chen <[email protected]>

________________________________
From: Liang, Prike <[email protected]>
Sent: Monday, August 3, 2026 11:16 PM
To: [email protected] <[email protected]>
Cc: Deucher, Alexander <[email protected]>; Koenig, Christian 
<[email protected]>; Chen, Michael <[email protected]>; Liu, Shaoyun 
<[email protected]>; Liang, Prike <[email protected]>
Subject: [PATCH v3 1/2] drm/amdgpu/mes: refactor the 
amdgpu_mes_alloc/free_proc|gang()

- Unify amdgpu_mes_alloc/free_proc|gang_ctx_index to provide
  centralized RS64mem bitmap management for both KGD and KFD.
- Retrieve the bitmap bit for userq contex index based on a
  per process granularity.

Signed-off-by: Prike Liang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c    | 28 +++++++++++-----------
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h    |  8 +++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c  |  6 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h  |  3 ++-
 drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 26 ++++++++++++++------
 5 files changed, 45 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 9af7c97af5be..5998e05ecd79 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -1040,13 +1040,13 @@ int amdgpu_mes_rs64mem_setup_bitmaps(struct amdgpu_mes 
*mes)
  * amdgpu_mes_alloc_proc_ctx_index - allocate a process context slot
  *
  * @mes: MES instance
- * @queue: Usermode queue receiving the allocated process context index
+ * @index: the allocated process context index
  *
  * Returns 0 on success, -ENOSPC if all slots are used, or
  * -EOPNOTSUPP if RS64 local memory is unavailable.
  */
 int amdgpu_mes_alloc_proc_ctx_index(struct amdgpu_mes *mes,
-                                   struct amdgpu_usermode_queue *queue)
+                                   uint32_t *index)
 {
         unsigned long bit;

@@ -1061,7 +1061,7 @@ int amdgpu_mes_alloc_proc_ctx_index(struct amdgpu_mes 
*mes,
                 return -ENOSPC;
         }
         set_bit(bit, mes->proc_ctx_bitmap);
-       queue->proc_ctx_array_index = (uint32_t)bit;
+       *index = (uint32_t)bit;
         amdgpu_mes_unlock(mes);

         return 0;
@@ -1071,18 +1071,18 @@ int amdgpu_mes_alloc_proc_ctx_index(struct amdgpu_mes 
*mes,
   * amdgpu_mes_free_proc_ctx_index - free a process context slot
   *
   * @mes: MES instance
-  * @queue: Usermode queue whose process context index is released
+  * @index: process context index is released
   */
 void amdgpu_mes_free_proc_ctx_index(struct amdgpu_mes *mes,
-                                   struct amdgpu_usermode_queue *queue)
+                                   uint32_t index)
 {
         if (!mes->use_rs64mem || !mes->proc_ctx_bitmap)
                 return;
-       if (queue->proc_ctx_array_index >= mes->proc_ctx_array_size)
+       if (index >= mes->proc_ctx_array_size)
                 return;

         amdgpu_mes_lock(mes);
-       clear_bit(queue->proc_ctx_array_index, mes->proc_ctx_bitmap);
+       clear_bit(index, mes->proc_ctx_bitmap);
         amdgpu_mes_unlock(mes);
 }

@@ -1090,13 +1090,13 @@ void amdgpu_mes_free_proc_ctx_index(struct amdgpu_mes 
*mes,
   * amdgpu_mes_alloc_gang_ctx_index - allocate a gang context slot
   *
   * @mes: MES instance
-  * @queue: Usermode queue receiving the allocated gang context index
+  * @index: the allocated gang context index
   *
   * Returns 0 on success, -ENOSPC if all slots are used, or
   * -EOPNOTSUPP if RS64 local memory is unavailable.
   */
 int amdgpu_mes_alloc_gang_ctx_index(struct amdgpu_mes *mes,
-                                   struct amdgpu_usermode_queue *queue)
+                                   uint32_t *index)
 {
         unsigned long bit;

@@ -1111,7 +1111,7 @@ int amdgpu_mes_alloc_gang_ctx_index(struct amdgpu_mes 
*mes,
                 return -ENOSPC;
         }
         set_bit(bit, mes->gang_ctx_bitmap);
-       queue->gang_ctx_array_index = bit;
+       *index = bit;
         amdgpu_mes_unlock(mes);

         return 0;
@@ -1121,18 +1121,18 @@ int amdgpu_mes_alloc_gang_ctx_index(struct amdgpu_mes 
*mes,
   * amdgpu_mes_free_gang_ctx_index - free a gang context slot
   *
   * @mes: MES instance
-  * @queue: Usermode queue whose gang context index is released
+  * @index: gang context index is released
   */
 void amdgpu_mes_free_gang_ctx_index(struct amdgpu_mes *mes,
-                                   struct amdgpu_usermode_queue *queue)
+                                   uint32_t index)
 {
         if (!mes->use_rs64mem || !mes->gang_ctx_bitmap)
                 return;
-       if (queue->gang_ctx_array_index >= mes->gang_ctx_array_size)
+       if (index >= mes->gang_ctx_array_size)
                 return;

         amdgpu_mes_lock(mes);
-       clear_bit(queue->gang_ctx_array_index, mes->gang_ctx_bitmap);
+       clear_bit(index, mes->gang_ctx_bitmap);
         amdgpu_mes_unlock(mes);
 }

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
index c67db2d6e122..977c057dcce8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
@@ -636,11 +636,11 @@ int amdgpu_mes_rs64mem_init(struct amdgpu_mes *mes);
 void amdgpu_mes_rs64mem_fini(struct amdgpu_mes *mes);
 int amdgpu_mes_rs64mem_setup_bitmaps(struct amdgpu_mes *mes);
 int amdgpu_mes_alloc_proc_ctx_index(struct amdgpu_mes *mes,
-                                   struct amdgpu_usermode_queue *queue);
+                                   uint32_t *index);
 void amdgpu_mes_free_proc_ctx_index(struct amdgpu_mes *mes,
-                                   struct amdgpu_usermode_queue *queue);
+                                   uint32_t index);
 int amdgpu_mes_alloc_gang_ctx_index(struct amdgpu_mes *mes,
-                                   struct amdgpu_usermode_queue *queue);
+                                   uint32_t *index);
 void amdgpu_mes_free_gang_ctx_index(struct amdgpu_mes *mes,
-                                   struct amdgpu_usermode_queue *queue);
+                                   uint32_t index);
 #endif /* __AMDGPU_MES_H__ */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index 571413c9a611..5dd4fe258cdb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -1244,6 +1244,7 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr 
*userq_mgr, struct drm_file *f
         xa_init_flags(&userq_mgr->userq_xa, XA_FLAGS_ALLOC);
         userq_mgr->adev = adev;
         userq_mgr->file = file_priv;
+       userq_mgr->proc_ctx_allocated = false;
         mutex_init(&userq_mgr->proc_ctx_lock);

         INIT_DELAYED_WORK(&userq_mgr->resume_work, 
amdgpu_userq_restore_worker);
@@ -1272,6 +1273,7 @@ void amdgpu_userq_mgr_cancel_resume(struct 
amdgpu_userq_mgr *userq_mgr)

 void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
 {
+       struct amdgpu_mes *mes = &userq_mgr->adev->mes;
         struct amdgpu_usermode_queue *queue;
         unsigned long queue_id = 0;

@@ -1298,6 +1300,10 @@ void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr 
*userq_mgr)
          */
         cancel_work_sync(&userq_mgr->reset_work);

+       if (userq_mgr->proc_ctx_allocated) {
+               amdgpu_mes_free_proc_ctx_index(mes, 
userq_mgr->proc_ctx_array_index);
+               userq_mgr->proc_ctx_allocated = false;
+       }
         amdgpu_bo_free_kernel(&userq_mgr->proc_ctx_obj.obj,
                               &userq_mgr->proc_ctx_obj.gpu_addr,
                               &userq_mgr->proc_ctx_obj.cpu_ptr);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
index 402dc2816f04..4dcf6151de6a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
@@ -101,7 +101,6 @@ struct amdgpu_usermode_queue {
                 u64 va_array[6];
         } userq_vas;

-       uint32_t        proc_ctx_array_index;
         uint32_t        gang_ctx_array_index;
 };

@@ -133,6 +132,8 @@ struct amdgpu_userq_mgr {
         struct mutex                    proc_ctx_lock;
         struct amdgpu_userq_obj         proc_ctx_obj;

+       bool                            proc_ctx_allocated;
+       uint32_t                        proc_ctx_array_index;
         /**
          * @reset_work:
          *
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c 
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index a914198a4d62..ae403bb89441 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -143,10 +143,24 @@ static int mes_userq_map(struct amdgpu_usermode_queue 
*queue)
         queue_input.doorbell_offset = userq_props->doorbell_index;
         queue_input.page_table_base_addr = 
amdgpu_gmc_pd_addr(queue->vm->root.bo);
         queue_input.wptr_mc_addr = queue->wptr_obj.gpu_addr;
+
         if (mes->use_rs64mem) {
-               amdgpu_mes_alloc_proc_ctx_index(mes, queue);
-               queue_input.process_context_array_index = 
queue->proc_ctx_array_index;
-               amdgpu_mes_alloc_gang_ctx_index(mes, queue);
+                if (!uq_mgr->proc_ctx_allocated) {
+                       r = amdgpu_mes_alloc_proc_ctx_index(mes, 
&uq_mgr->proc_ctx_array_index);
+                       if (r) {
+                               DRM_ERROR("Failed to allocate userq process 
index err:%d\n", r);
+                               return r;
+                       }
+                       uq_mgr->proc_ctx_allocated = true;
+               }
+
+               r = amdgpu_mes_alloc_gang_ctx_index(mes, 
&queue->gang_ctx_array_index);
+               if (r) {
+                       DRM_ERROR("Failed to allocate userq gang index 
err:%d\n", r);
+                       amdgpu_mes_free_gang_ctx_index(mes, 
queue->gang_ctx_array_index);

No need to call free on failure, otherwise it will free index '0' accidentally.

+                       return r;
+               }
+               queue_input.process_context_array_index = 
uq_mgr->proc_ctx_array_index;
                 queue_input.gang_context_array_index = 
queue->gang_ctx_array_index;
         }
         amdgpu_mes_lock(&adev->mes);
@@ -179,10 +193,8 @@ static int mes_userq_unmap(struct amdgpu_usermode_queue 
*queue)
         amdgpu_mes_lock(&adev->mes);
         r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
         amdgpu_mes_unlock(&adev->mes);
-       if (mes->use_rs64mem) {
-               amdgpu_mes_free_proc_ctx_index(mes, queue);
-               amdgpu_mes_free_gang_ctx_index(mes, queue);
-       }
+       if (mes->use_rs64mem)
+               amdgpu_mes_free_gang_ctx_index(mes, 
queue->gang_ctx_array_index);
         if (r)
                 DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
         return r;
--
2.34.1

Reply via email to