A queue MODIFY (e.g. re-enabling a queue after a queue_percentage == 0
disable) must not rebuild the MQD with init_mqd: init_mqd rebuilds the HQD
from power-on defaults and zeroes the ring pointers, discarding the state
firmware context-saved into the MQD on unmap. The re-mapped engine then
comes up idle, drops the packet queued while disabled, and wedges into a
GPU reset.

Add an optional update_mqd hook to struct amdgpu_mqd for IPs to patch the
MQD in place instead - preserving the saved ring/HQD state and forwarding
user_wptr into the MQD write pointer. KFD already handles the same
disable/re-enable sequence by patching the MQD in place rather than
re-initialising it.

Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
index 63670b41c26c..2f73eceea57d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
@@ -500,6 +500,12 @@ struct amdgpu_mqd {
        unsigned mqd_size;
        int (*init_mqd)(struct amdgpu_device *adev, void *mqd,
                        struct amdgpu_mqd_prop *p);
+       /* Patch an MQD in place for a queue MODIFY: keep the ring/HQD state
+        * firmware context-saved into it (init_mqd instead rebuilds from
+        * defaults) and forward @user_wptr into the MQD write pointer.
+        */
+       int (*update_mqd)(struct amdgpu_device *adev, void *mqd,
+                         struct amdgpu_mqd_prop *p, u64 user_wptr);
 };
 
 /*
-- 
2.49.0

Reply via email to