Re: [PATCH V2] drm/amdgpu: properly account for resets with user queues

"Lazar, Lijo" <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>

On 14-Jul-26 9:25 PM, Alex Deucher wrote:
> We need to increment the reset counter, force fence completion,
> and set the wedged event when a user queue is reset, but only
> for the guilty queue.  We don't want additional events for
> collateral damage.
> 
> Only increment the reset counter and set the wedged event
> in the top level userq reset callers (both KGD and KFD).
> This aligns with how this is managed for kernel queue resets.
> 
> v2: fix task info refcount handling, align with
>      kfd error reporting.
> 
> Signed-off-by: Alex Deucher <[email protected]>
> Cc: Srinivasan Shanmugam <[email protected]>
> Cc: Prike Liang <[email protected]>
> Cc: Sunil Khatri <[email protected]>
> Cc: Lazar, Lijo <[email protected]>
> ---

Reviewed-by: Lijo Lazar <[email protected]>

Thanks,
Lijo

>   drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c      | 18 +++++++++++++++++-
>   drivers/gpu/drm/amd/amdgpu/mes_userqueue.c     |  2 --
>   .../drm/amd/amdkfd/kfd_device_queue_manager.c  | 17 ++++++++++++++++-
>   3 files changed, 33 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> index 6aa75da27f912..58754fc41bb6c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> @@ -123,6 +123,8 @@ static void amdgpu_userq_hang_detect_work(struct work_struct *work)
>   	struct amdgpu_device *adev = uq_mgr->adev;
>   	const struct amdgpu_userq_funcs *userq_funcs =
>   		adev->userq_funcs[queue->queue_type];
> +	struct drm_wedge_task_info *info = NULL;
> +	struct amdgpu_task_info *ti = NULL;
>   	bool gpu_reset = false;
>   
>   	if (unlikely(adev->debug_disable_gpu_ring_reset)) {
> @@ -137,6 +139,14 @@ static void amdgpu_userq_hang_detect_work(struct work_struct *work)
>   	if (!amdgpu_gpu_recovery)
>   		return;
>   
> +	if (queue->vm && queue->vm->pasid) {
> +		ti = amdgpu_vm_get_task_info_pasid(adev, queue->vm->pasid);
> +		if (ti) {
> +			amdgpu_vm_print_task_info(adev, ti);
> +			info = &ti->task;
> +		}
> +	}
> +
>   	if (amdgpu_userq_is_reset_type_supported(adev, queue->queue_type,
>   						 AMDGPU_RESET_TYPE_PER_QUEUE)) {
>   		int r;
> @@ -146,11 +156,17 @@ static void amdgpu_userq_hang_detect_work(struct work_struct *work)
>   							 queue, NULL, NULL);
>   		else
>   			r = userq_funcs->reset(queue);
> -		if (r)
> +		if (r) {
>   			gpu_reset = true;
> +		} else {
> +			atomic_inc(&adev->gpu_reset_counter);
> +			amdgpu_userq_fence_driver_force_completion(queue);
> +			drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, info);
> +		}
>   	} else {
>   		gpu_reset = true;
>   	}
> +	amdgpu_vm_put_task_info(ti);
>   
>   	/*
>   	 * Don't schedule the work here! Scheduling or queue work from one reset
> diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
> index d3d79bbaf9eb7..a1371a9f961d1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
> @@ -234,9 +234,7 @@ int mes_userq_reset_queue(struct amdgpu_device *adev,
>   				r = mes_userq_unmap(uq);
>   				if (r)
>   					return r;
> -				atomic_inc(&adev->gpu_reset_counter);
>   				amdgpu_userq_fence_driver_force_completion(uq);
> -				drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, NULL);
>   				break;
>   			}
>   		}
> 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 0419fe869d4b0..58ccbf955f287 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> @@ -448,6 +448,9 @@ int kfd_reset_queue_mes(struct device_queue_manager *dqm, int queue_type,
>   static int reset_queues_mes(struct device_queue_manager *dqm, struct queue *q)
>   {
>   	struct amdgpu_device *adev = (struct amdgpu_device *)dqm->dev->adev;
> +	struct drm_wedge_task_info *info = NULL;
> +	struct amdgpu_task_info *ti = NULL;
> +	struct kfd_process_device *pdd;
>   	unsigned int num_hung = 0;
>   	int r = 0;
>   	struct mes_remove_queue_input queue_input;
> @@ -476,13 +479,25 @@ static int reset_queues_mes(struct device_queue_manager *dqm, struct queue *q)
>   	r = amdgpu_gfx_reset_mes_compute(adev, NULL, NULL, NULL, &num_hung, &queue_input);
>   	if (r)
>   		goto fail;
> +	pdd = kfd_get_process_device_data(q->device, q->process);
> +	if (pdd) {
> +		ti = amdgpu_vm_get_task_info_pasid(adev, pdd->pasid);
> +		if (ti) {
> +			amdgpu_vm_print_task_info(adev, ti);
> +			info = &ti->task;
> +		}
> +	}
>   
>   	dqm->detect_hang_count = num_hung;
>   	/* When MES doesn't detect any queue hang, no reset happens. Don't signal reset
>   	 * event.
>   	 */
> -	if (dqm->detect_hang_count)
> +	if (dqm->detect_hang_count) {
>   		kfd_signal_reset_event(dqm->dev);
> +		atomic_inc(&adev->gpu_reset_counter);
> +		drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, info);
> +	}
> +	amdgpu_vm_put_task_info(ti);
>   
>   fail:
>   	dqm->detect_hang_count = 0;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.