From: Chunming Zhou <david1.z...@amd.com>

v2: rebase against kfd changes

Signed-off-by: Chunming Zhou <david1.zhou at amd.com>
Acked-by: Christian K?nig <christian.koenig at amd.com>
Reviewed-by: Jammy Zhou <Jammy.Zhou at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  3 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c    | 83 +++++++++++++++++++++---------
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  9 ++++
 3 files changed, 71 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index d85df45..a9be614 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2058,6 +2058,9 @@ struct amdgpu_device {

        /* amdkfd interface */
        struct kfd_dev          *kfd;
+
+       /* kernel conext for IB submission */
+       struct amdgpu_ctx *kernel_ctx;
 };

 bool amdgpu_device_is_px(struct drm_device *dev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 41bc7fc..a5d8242 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -48,33 +48,53 @@ static void amdgpu_ctx_do_release(struct kref *ref)
        kfree(ctx);
 }

+static void amdgpu_ctx_init(struct amdgpu_device *adev,
+                           struct amdgpu_fpriv *fpriv,
+                           struct amdgpu_ctx *ctx,
+                           uint32_t id)
+{
+       int i;
+       memset(ctx, 0, sizeof(*ctx));
+       ctx->adev = adev;
+       kref_init(&ctx->refcount);
+       spin_lock_init(&ctx->ring_lock);
+       for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
+               ctx->rings[i].sequence = 1;
+}
+
 int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
                     uint32_t *id)
 {
        struct amdgpu_ctx *ctx;
-       struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
        int i, j, r;

        ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
                return -ENOMEM;
-
-       mutex_lock(&mgr->lock);
-       r = idr_alloc(&mgr->ctx_handles, ctx, 0, 0, GFP_KERNEL);
-       if (r < 0) {
+       if (fpriv) {
+               struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
+               mutex_lock(&mgr->lock);
+               r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL);
+               if (r < 0) {
+                       mutex_unlock(&mgr->lock);
+                       kfree(ctx);
+                       return r;
+               }
+               *id = (uint32_t)r;
+               amdgpu_ctx_init(adev, fpriv, ctx, *id);
                mutex_unlock(&mgr->lock);
-               kfree(ctx);
-               return r;
+       } else {
+               if (adev->kernel_ctx) {
+                       DRM_ERROR("kernel cnotext has been created.\n");
+                       kfree(ctx);
+                       return 0;
+               }
+               *id = AMD_KERNEL_CONTEXT_ID;
+               amdgpu_ctx_init(adev, fpriv, ctx, *id);
+
+               adev->kernel_ctx = ctx;
        }
-       *id = (uint32_t)r;

-       memset(ctx, 0, sizeof(*ctx));
-       ctx->adev = adev;
-       kref_init(&ctx->refcount);
-       spin_lock_init(&ctx->ring_lock);
-       for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
-               ctx->rings[i].sequence = 1;
-       mutex_unlock(&mgr->lock);
        if (amdgpu_enable_scheduler) {
                /* create context entity for each ring */
                for (i = 0; i < adev->num_rings; i++) {
@@ -105,17 +125,23 @@ int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct 
amdgpu_fpriv *fpriv,
 int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, 
uint32_t id)
 {
        struct amdgpu_ctx *ctx;
-       struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;

-       mutex_lock(&mgr->lock);
-       ctx = idr_find(&mgr->ctx_handles, id);
-       if (ctx) {
-               idr_remove(&mgr->ctx_handles, id);
-               kref_put(&ctx->refcount, amdgpu_ctx_do_release);
+       if (fpriv) {
+               struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
+               mutex_lock(&mgr->lock);
+               ctx = idr_find(&mgr->ctx_handles, id);
+               if (ctx) {
+                       idr_remove(&mgr->ctx_handles, id);
+                       kref_put(&ctx->refcount, amdgpu_ctx_do_release);
+                       mutex_unlock(&mgr->lock);
+                       return 0;
+               }
                mutex_unlock(&mgr->lock);
+       } else {
+               ctx = adev->kernel_ctx;
+               kref_put(&ctx->refcount, amdgpu_ctx_do_release);
                return 0;
        }
-       mutex_unlock(&mgr->lock);
        return -EINVAL;
 }

@@ -124,9 +150,13 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev,
                            union drm_amdgpu_ctx_out *out)
 {
        struct amdgpu_ctx *ctx;
-       struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
+       struct amdgpu_ctx_mgr *mgr;
        unsigned reset_counter;

+       if (!fpriv)
+               return -EINVAL;
+
+       mgr = &fpriv->ctx_mgr;
        mutex_lock(&mgr->lock);
        ctx = idr_find(&mgr->ctx_handles, id);
        if (!ctx) {
@@ -202,7 +232,12 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
 struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
 {
        struct amdgpu_ctx *ctx;
-       struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
+       struct amdgpu_ctx_mgr *mgr;
+
+       if (!fpriv)
+               return NULL;
+
+       mgr = &fpriv->ctx_mgr;

        mutex_lock(&mgr->lock);
        ctx = idr_find(&mgr->ctx_handles, id);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 4b641f3..7e39b72 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1517,6 +1517,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,
                return r;
        }

+       if (!adev->kernel_ctx) {
+               uint32_t id = 0;
+               r = amdgpu_ctx_alloc(adev, NULL, &id);
+               if (r) {
+                       dev_err(adev->dev, "failed to create kernel context 
(%d).\n", r);
+                       return r;
+               }
+       }
        r = amdgpu_ib_ring_tests(adev);
        if (r)
                DRM_ERROR("ib ring test failed (%d).\n", r);
@@ -1578,6 +1586,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
        adev->shutdown = true;
        /* evict vram memory */
        amdgpu_bo_evict_vram(adev);
+       amdgpu_ctx_free(adev, NULL, 0);
        amdgpu_ib_pool_fini(adev);
        amdgpu_fence_driver_fini(adev);
        amdgpu_fbdev_fini(adev);
-- 
1.8.3.1

Reply via email to