Report an ongoing GPU reset through RESET_IN_PROGRESS at bit 1, alongside BROKEN at bit 0, so userspace can query whether GPU recovery is ongoing.
Validate query inputs using the same rules as queue deletion and document the required fields. Drop the queue reference after releasing userq_mutex because the final put may destroy the queue and acquire that mutex. Signed-off-by: Prike Liang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 6 +++++- include/uapi/drm/amdgpu_drm.h | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 6340e647a67d..6c4743ddf04a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -835,8 +835,11 @@ amdgpu_userq_query_status(struct drm_file *filp, union drm_amdgpu_userq *args) queue->state == AMDGPU_USERQ_STATE_INVALID_VA || queue->generation != amdgpu_vm_generation(adev, &fpriv->vm)) args->out_qs.flags |= AMDGPU_USERQ_QUERY_STATUS_FLAGS_BROKEN; - amdgpu_userq_put(queue); + if (amdgpu_in_reset(adev)) + args->out_qs.flags |= AMDGPU_USERQ_QUERY_STATUS_FLAGS_RESET_IN_PROGRESS; mutex_unlock(&uq_mgr->userq_mutex); + /* The final put may destroy the queue and take userq_mutex. */ + amdgpu_userq_put(queue); return 0; } @@ -898,6 +901,7 @@ static int amdgpu_userq_input_args_validate(struct drm_device *dev, } break; case AMDGPU_USERQ_OP_FREE: + case AMDGPU_USERQ_OP_QUERY_STATUS: if (args->in.ip_type || args->in.doorbell_handle || args->in.doorbell_offset || diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 98c3fa8a4a72..32ed4c4349a4 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -355,19 +355,21 @@ union drm_amdgpu_ctx { /* the queue is broken because it is hung, has an invalid VA, or VRAM was lost */ #define AMDGPU_USERQ_QUERY_STATUS_FLAGS_BROKEN (1 << 0) +/* indicate that a GPU reset has not completed yet */ +#define AMDGPU_USERQ_QUERY_STATUS_FLAGS_RESET_IN_PROGRESS (1 << 1) /* * This structure is a container to pass input configuration * info for all supported userqueue related operations. * For operation AMDGPU_USERQ_OP_CREATE: user is expected * to set all fields, excep the parameter 'queue_id'. - * For operation AMDGPU_USERQ_OP_FREE: the only input parameter expected - * to be set is 'queue_id', eveything else is ignored. + * For operations AMDGPU_USERQ_OP_FREE and AMDGPU_USERQ_OP_QUERY_STATUS: + * only 'op' and 'queue_id' should be set; all other fields must be zero. */ struct drm_amdgpu_userq_in { /** AMDGPU_USERQ_OP_* */ __u32 op; - /** Queue id passed for operation USERQ_OP_FREE */ + /** Queue id passed for operations USERQ_OP_FREE and USERQ_OP_QUERY_STATUS */ __u32 queue_id; /** the target GPU engine to execute workload (AMDGPU_HW_IP_*) */ __u32 ip_type; -- 2.34.1
