summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2026-05-18 12:37:19 -0400
committerAlex Deucher <alexander.deucher@amd.com>2026-06-17 15:51:35 -0400
commit47f1a5dafd7704c9fc729dad76a37231c93694bd (patch)
treea5a6175f7b5ddd70850527a544e1843b3760ffa0 /drivers/gpu/drm/amd
parent7b806702e0794fc355c104db8c5bbc3021fa0158 (diff)
downloadlinux-next-47f1a5dafd7704c9fc729dad76a37231c93694bd.tar.gz
linux-next-47f1a5dafd7704c9fc729dad76a37231c93694bd.zip
drm/amdkfd: plumb a helper to reset a KFD user queue
Can be called from KGD. Reviewed-by: Amber Lin <Amber.Lin@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h16
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device.c24
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c11
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h2
5 files changed, 66 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
index 9783a3cefb04..f25759962e0c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -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);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 5333e052d56d..d403af5fb552 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -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 */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 5eb863dec8f4..b40b6a566aae 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -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
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 54c19d31e30e..d2c81a79b614 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -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;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index e0b6a47e7722..2229f8b2f446 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -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)
{