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

Reply via email to