Identical in principle to DRM_IOCTL_GEM_CHANGE_HANDLE, we need a method
for renaming the driver specific context handles.

We add a new operation (AMDGPU_CTX_OP_CHANGE_HANDLE) to the
DRM_IOCTL_AMDGPU_CTX ioctl.

Source handle is given in the existing input handle field, while the
destination handle needs to be passed in the existing flags field.

Signed-off-by: Tvrtko Ursulin <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 41 +++++++++++++++++++++++++
 include/uapi/drm/amdgpu_drm.h           |  1 +
 2 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 59ea6153f4a2..771c128571fe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -517,6 +517,44 @@ static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, 
uint32_t id)
        return ctx ? 0 : -EINVAL;
 }
 
+static int amdgpu_ctx_change_handle(struct amdgpu_fpriv *fpriv,
+                                   uint32_t old, uint32_t id)
+{
+       struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
+       XA_STATE(xas, &mgr->ctx_handles, id);
+       struct amdgpu_ctx *ctx;
+       int r;
+
+       if (!old || !id || old == id)
+               return -EINVAL;
+
+       do {
+               xas_lock(&xas);
+
+               ctx = xa_load(&mgr->ctx_handles, old);
+               if (!ctx) {
+                       r = -EINVAL;
+                       goto unlock;
+               }
+
+               if (xas_load(&xas)) {
+                       r = -EBUSY;
+                       goto unlock;
+               }
+
+               xas_store(&xas, ctx);
+               r = xas_error(&xas);
+               if (r)
+                       goto unlock;
+
+               __xa_erase(&mgr->ctx_handles, old);
+unlock:
+               xas_unlock(&xas);
+       } while (xas_nomem(&xas, GFP_KERNEL));
+
+       return r;
+}
+
 static int amdgpu_ctx_query(struct amdgpu_device *adev,
                            struct amdgpu_fpriv *fpriv, uint32_t id,
                            union drm_amdgpu_ctx_out *out)
@@ -710,6 +748,9 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
                        return -EINVAL;
                r = amdgpu_ctx_stable_pstate(adev, fpriv, id, true, 
&stable_pstate);
                break;
+       case AMDGPU_CTX_OP_CHANGE_HANDLE:
+               r = amdgpu_ctx_change_handle(fpriv, id, args->in.flags);
+               break;
        default:
                return -EINVAL;
        }
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 27b32eed6f3a..28cebf7a3cd6 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -253,6 +253,7 @@ union drm_amdgpu_bo_list {
 #define AMDGPU_CTX_OP_QUERY_STATE2     4
 #define AMDGPU_CTX_OP_GET_STABLE_PSTATE        5
 #define AMDGPU_CTX_OP_SET_STABLE_PSTATE        6
+#define AMDGPU_CTX_OP_CHANGE_HANDLE    7
 
 /* GPU reset status */
 #define AMDGPU_CTX_NO_RESET            0
-- 
2.54.0

Reply via email to