From: Chunming Zhou <david1.zhou@xxxxxxx> v2: rebase against kfd changes Signed-off-by: Chunming Zhou <david1.zhou@xxxxxxx> Acked-by: Christian K?nig <christian.koenig@xxxxxxx> Reviewed-by: Jammy Zhou <Jammy.Zhou@xxxxxxx> --- 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel