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;