[PATCH 08/10] drm/amdgpu/mes_userqueue: route compute MODIFY through update_mqd

Jesse Zhang <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
Call the per-IP update_mqd callback instead of init_mqd for a compute
MODIFY, so a queue re-enabled after a queue_percentage == 0 disable keeps
its ring position instead of wedging into a GPU reset (see the update_mqd
callback commit for why). Add mes_userq_read_user_wptr() to read the
current user wptr and forward it to the callback.

Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 28 +++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index 82bb4369451e..f2742fa28dc6 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -681,6 +681,25 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
 	return r;
 }
 
+/*
+ * Read the queue's current user wptr from its wptr poll BO. Packets queued
+ * while the queue was disabled advanced this value but not the MQD; the per-IP
+ * update_mqd callback forwards it back into the MQD so a re-enabled queue picks
+ * the work up. Returns 0 if the BO is not mapped.
+ */
+static u64 mes_userq_read_user_wptr(struct amdgpu_usermode_queue *queue)
+{
+	u64 user_wptr = 0;
+	void *wc = NULL;
+
+	if (queue->wptr_obj.obj &&
+	    !amdgpu_bo_kmap(queue->wptr_obj.obj, &wc) && wc) {
+		user_wptr = *(volatile u64 *)wc;
+		amdgpu_bo_kunmap(queue->wptr_obj.obj);
+	}
+	return user_wptr;
+}
+
 static int mes_userq_compute_mqd_update(struct amdgpu_usermode_queue *queue,
 					struct drm_amdgpu_userq_in *args_in)
 {
@@ -695,6 +714,11 @@ static int mes_userq_compute_mqd_update(struct amdgpu_usermode_queue *queue,
 		return -EINVAL;
 	}
 
+	if (!mqd_hw_default->update_mqd) {
+		DRM_ERROR("Compute MQD update not supported on this IP\n");
+		return -EOPNOTSUPP;
+	}
+
 	compute_mqd_v11 = memdup_user(u64_to_user_ptr(args_in->mqd), args_in->mqd_size);
 	if (IS_ERR(compute_mqd_v11)) {
 		DRM_ERROR("Failed to read user MQD\n");
@@ -708,7 +732,9 @@ static int mes_userq_compute_mqd_update(struct amdgpu_usermode_queue *queue,
 	userq_props->queue_size = args_in->queue_size;
 	userq_props->hqd_base_gpu_addr = args_in->queue_va;
 
-	retval = mqd_hw_default->init_mqd(adev, (void *)queue->mqd.cpu_ptr, userq_props);
+	retval = mqd_hw_default->update_mqd(adev, (void *)queue->mqd.cpu_ptr,
+					    userq_props,
+					    mes_userq_read_user_wptr(queue));
 
 free:
 	kfree(compute_mqd_v11);
-- 
2.49.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.