diff options
author | Christian König <christian.koenig@amd.com> | 2015-08-04 17:51:05 +0200 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-08-17 16:51:02 -0400 |
commit | 47f38501f11fa45d8a7797f1965448c1e20049d4 (patch) | |
tree | 67bba28445392c7584477178fce996a412e72dc3 /drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | |
parent | 0e89d0c16b9446a094215e71734e583c438bf83d (diff) |
drm/amdgpu: cleanup amdgpu_ctx inti/fini v2
Cleanup the kernel context handling.
v2: rebased
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com> (v1)
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 145 |
1 files changed, 68 insertions, 77 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index c2290ae20312..08a9292729dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -25,82 +25,27 @@ #include <drm/drmP.h> #include "amdgpu.h" -static void amdgpu_ctx_do_release(struct kref *ref) +int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel, + struct amdgpu_ctx *ctx) { - struct amdgpu_ctx *ctx; - struct amdgpu_device *adev; unsigned i, j; + int r; - ctx = container_of(ref, struct amdgpu_ctx, refcount); - adev = ctx->adev; - - - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) - for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j) - fence_put(ctx->rings[i].fences[j]); - - if (amdgpu_enable_scheduler) { - for (i = 0; i < adev->num_rings; i++) - amd_context_entity_fini(adev->rings[i]->scheduler, - &ctx->rings[i].c_entity); - } - - kfree(ctx); -} - -static void amdgpu_ctx_init(struct amdgpu_device *adev, - struct amdgpu_fpriv *fpriv, - struct amdgpu_ctx *ctx) -{ - 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; - int i, j, r; - - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - 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); - mutex_unlock(&mgr->lock); - } else { - if (adev->kernel_ctx) { - DRM_ERROR("kernel cnotext has been created.\n"); - kfree(ctx); - return 0; - } - amdgpu_ctx_init(adev, fpriv, ctx); - - adev->kernel_ctx = ctx; - } if (amdgpu_enable_scheduler) { /* create context entity for each ring */ for (i = 0; i < adev->num_rings; i++) { struct amd_run_queue *rq; - if (fpriv) - rq = &adev->rings[i]->scheduler->sched_rq; - else + if (kernel) rq = &adev->rings[i]->scheduler->kernel_rq; + else + rq = &adev->rings[i]->scheduler->sched_rq; r = amd_context_entity_init(adev->rings[i]->scheduler, &ctx->rings[i].c_entity, NULL, rq, amdgpu_sched_jobs); @@ -113,33 +58,79 @@ int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, amd_context_entity_fini(adev->rings[j]->scheduler, &ctx->rings[j].c_entity); kfree(ctx); - return -EINVAL; + return r; } } - return 0; } -int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id) +void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) { + struct amdgpu_device *adev = ctx->adev; + unsigned i, j; + + for (i = 0; i < AMDGPU_MAX_RINGS; ++i) + for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j) + fence_put(ctx->rings[i].fences[j]); + + if (amdgpu_enable_scheduler) { + for (i = 0; i < adev->num_rings; i++) + amd_context_entity_fini(adev->rings[i]->scheduler, + &ctx->rings[i].c_entity); + } +} + +static int amdgpu_ctx_alloc(struct amdgpu_device *adev, + struct amdgpu_fpriv *fpriv, + uint32_t *id) +{ + struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; struct amdgpu_ctx *ctx; + int r; - 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; - } + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + mutex_lock(&mgr->lock); + r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL); + if (r < 0) { mutex_unlock(&mgr->lock); - } else { - ctx = adev->kernel_ctx; + kfree(ctx); + return r; + } + *id = (uint32_t)r; + r = amdgpu_ctx_init(adev, false, ctx); + mutex_unlock(&mgr->lock); + + return r; +} + +static void amdgpu_ctx_do_release(struct kref *ref) +{ + struct amdgpu_ctx *ctx; + + ctx = container_of(ref, struct amdgpu_ctx, refcount); + + amdgpu_ctx_fini(ctx); + + kfree(ctx); +} + +static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id) +{ + struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; + struct amdgpu_ctx *ctx; + + 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); return -EINVAL; } @@ -198,7 +189,7 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, args->out.alloc.ctx_id = id; break; case AMDGPU_CTX_OP_FREE_CTX: - r = amdgpu_ctx_free(adev, fpriv, id); + r = amdgpu_ctx_free(fpriv, id); break; case AMDGPU_CTX_OP_QUERY_STATE: r = amdgpu_ctx_query(adev, fpriv, id, &args->out); |