]> git.hungrycats.org Git - linux/commitdiff
drm/amdkfd: plumb a helper to reset a KFD user queue
authorAlex Deucher <alexander.deucher@amd.com>
Mon, 18 May 2026 16:37:19 +0000 (12:37 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 17 Jun 2026 19:51:35 +0000 (15:51 -0400)
Can be called from KGD.

Reviewed-by: Amber Lin <Amber.Lin@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h

index 9783a3cefb04b0c2dc75c419a9cb716a894440d3..f25759962e0c9b750e93403a339b9061cbd8cfa0 100644 (file)
@@ -942,3 +942,17 @@ int amdgpu_amdkfd_config_sq_perfmon(struct amdgpu_device *adev, uint32_t xcp_id,
 
        return r;
 }
+
+/* Reset an MES queue */
+int amdgpu_amdkfd_reset_mes_queue(struct amdgpu_device *adev,
+                                 uint32_t node_id,
+                                 int queue_type,
+                                 int pipe, int queue,
+                                 unsigned int db)
+{
+       if (!adev->kfd.init_complete)
+               return 0;
+
+       return kgd2kfd_reset_mes_queue(adev->kfd.dev, node_id, queue_type,
+                                      pipe, queue, db);
+}
index 5333e052d56db6a988a07c077d24f59d1f0efe32..d403af5fb5526b6e000dbb198ef1b33d72e1b78b 100644 (file)
@@ -275,7 +275,11 @@ int amdgpu_amdkfd_stop_sched(struct amdgpu_device *adev, uint32_t node_id);
 int amdgpu_amdkfd_config_sq_perfmon(struct amdgpu_device *adev, uint32_t xcp_id,
        bool core_override_enable, bool reg_override_enable, bool perfmon_override_enable);
 bool amdgpu_amdkfd_compute_active(struct amdgpu_device *adev, uint32_t node_id);
-
+int amdgpu_amdkfd_reset_mes_queue(struct amdgpu_device *adev,
+                                 uint32_t node_id,
+                                 int queue_type,
+                                 int pipe, int queue,
+                                 unsigned int db);
 
 /* Read user wptr from a specified user address space with page fault
  * disabled. The memory must be pinned and mapped to the hardware when
@@ -446,6 +450,9 @@ bool kgd2kfd_vmfault_fast_path(struct amdgpu_device *adev, struct amdgpu_iv_entr
                               bool retry_fault);
 void kgd2kfd_lock_kfd(void);
 void kgd2kfd_teardown_processes(struct amdgpu_device *adev);
+int kgd2kfd_reset_mes_queue(struct kfd_dev *kfd, uint32_t node_id,
+                           int queue_type, int pipe, int queue,
+                           unsigned int db);
 
 #else
 static inline int kgd2kfd_init(void)
@@ -576,5 +583,12 @@ static inline void kgd2kfd_teardown_processes(struct amdgpu_device *adev)
 {
 }
 
+static inline int kgd2kfd_reset_mes_queue(struct kfd_dev *kfd, uint32_t node_id,
+                                         int queue_type, int pipe, int queue,
+                                         unsigned int db)
+{
+       return 0;
+}
+
 #endif
 #endif /* AMDGPU_AMDKFD_H_INCLUDED */
index 5eb863dec8f4d6975ffe3429a6831d19c6299b76..b40b6a566aaeae913353c2bf145f3c9212b7e72a 100644 (file)
@@ -1796,6 +1796,30 @@ void kgd2kfd_teardown_processes(struct amdgpu_device *adev)
                cond_resched();
 }
 
+int kgd2kfd_reset_mes_queue(struct kfd_dev *kfd, uint32_t node_id,
+                           int queue_type, int pipe, int queue,
+                           unsigned int db)
+{
+       struct kfd_node *node;
+       int ret;
+
+       if (!kfd->init_complete)
+               return 0;
+
+       if (node_id >= kfd->num_nodes) {
+               dev_warn(kfd->adev->dev, "Invalid node ID: %u exceeds %u\n",
+                        node_id, kfd->num_nodes - 1);
+               return -EINVAL;
+       }
+       node = kfd->nodes[node_id];
+
+       ret = kfd_reset_queue_mes(node->dqm, queue_type, pipe, queue, db);
+       if (ret)
+               dev_err(kfd_device, "Error resetting queue\n");
+
+       return ret;
+}
+
 #if defined(CONFIG_DEBUG_FS)
 
 /* This function will send a package to HIQ to hang the HWS
index 54c19d31e30e234be08043d27a3043b7e8029fdc..d2c81a79b6148c307b44373224de91ad19819ed3 100644 (file)
@@ -433,6 +433,17 @@ static int reset_queue_mes(struct device_queue_manager *dqm, struct queue *q,
        return 0;
 }
 
+int kfd_reset_queue_mes(struct device_queue_manager *dqm, int queue_type,
+                       int pipe, int queue, unsigned int db)
+{
+       struct queue *q;
+
+       q = find_queue_by_doorbell_offset(dqm, db);
+       if (!q)
+               return 0;
+       return reset_queue_mes(dqm, q, queue_type, pipe, queue, db);
+}
+
 static int reset_queues_mes(struct device_queue_manager *dqm)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)dqm->dev->adev;
index e0b6a47e7722b9b66ea7e25ec3c9a7e6744cb5a9..2229f8b2f44625eba6f15bfd92a25a5d9f2be7c1 100644 (file)
@@ -333,6 +333,8 @@ int debug_refresh_runlist(struct device_queue_manager *dqm);
 bool kfd_dqm_is_queue_in_process(struct device_queue_manager *dqm,
                                 struct qcm_process_device *qpd,
                                 int doorbell_off, u32 *queue_format);
+int kfd_reset_queue_mes(struct device_queue_manager *dqm, int queue_type,
+                       int pipe, int queue, unsigned int db);
 
 static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd)
 {