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>
This commit is contained in:
Alex Deucher 2026-05-18 12:37:19 -04:00
parent 7b806702e0
commit 47f1a5dafd
5 changed files with 66 additions and 1 deletions

View 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);
}

View 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 */

View 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

View 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;

View 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)
{