From 47f1a5dafd7704c9fc729dad76a37231c93694bd Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 18 May 2026 12:37:19 -0400 Subject: drm/amdkfd: plumb a helper to reset a KFD user queue Can be called from KGD. Reviewed-by: Amber Lin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 14 +++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 16 ++++++++++++++- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 24 ++++++++++++++++++++++ .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 11 ++++++++++ .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 2 ++ 5 files changed, 66 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd') 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) { -- cgit v1.2.3