Commit 47f38501 authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: cleanup amdgpu_ctx inti/fini v2

Cleanup the kernel context handling.

v2: rebased
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com> (v1)
parent 0e89d0c1
...@@ -1033,10 +1033,9 @@ struct amdgpu_ctx_mgr { ...@@ -1033,10 +1033,9 @@ struct amdgpu_ctx_mgr {
struct idr ctx_handles; struct idr ctx_handles;
}; };
int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
uint32_t *id); struct amdgpu_ctx *ctx);
int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, void amdgpu_ctx_fini(struct amdgpu_ctx *ctx);
uint32_t id);
struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id);
int amdgpu_ctx_put(struct amdgpu_ctx *ctx); int amdgpu_ctx_put(struct amdgpu_ctx *ctx);
...@@ -2095,7 +2094,7 @@ struct amdgpu_device { ...@@ -2095,7 +2094,7 @@ struct amdgpu_device {
struct kfd_dev *kfd; struct kfd_dev *kfd;
/* kernel conext for IB submission */ /* kernel conext for IB submission */
struct amdgpu_ctx *kernel_ctx; struct amdgpu_ctx kernel_ctx;
}; };
bool amdgpu_device_is_px(struct drm_device *dev); bool amdgpu_device_is_px(struct drm_device *dev);
......
...@@ -25,15 +25,49 @@ ...@@ -25,15 +25,49 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include "amdgpu.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; unsigned i, j;
int r;
ctx = container_of(ref, struct amdgpu_ctx, refcount); memset(ctx, 0, sizeof(*ctx));
adev = ctx->adev; 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;
if (amdgpu_enable_scheduler) {
/* create context entity for each ring */
for (i = 0; i < adev->num_rings; i++) {
struct amd_run_queue *rq;
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);
if (r)
break;
}
if (i < adev->num_rings) {
for (j = 0; j < i; j++)
amd_context_entity_fini(adev->rings[j]->scheduler,
&ctx->rings[j].c_entity);
kfree(ctx);
return r;
}
}
return 0;
}
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 (i = 0; i < AMDGPU_MAX_RINGS; ++i)
for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j) for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j)
...@@ -44,34 +78,20 @@ static void amdgpu_ctx_do_release(struct kref *ref) ...@@ -44,34 +78,20 @@ static void amdgpu_ctx_do_release(struct kref *ref)
amd_context_entity_fini(adev->rings[i]->scheduler, amd_context_entity_fini(adev->rings[i]->scheduler,
&ctx->rings[i].c_entity); &ctx->rings[i].c_entity);
} }
kfree(ctx);
} }
static void amdgpu_ctx_init(struct amdgpu_device *adev, static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
struct amdgpu_fpriv *fpriv, 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) uint32_t *id)
{ {
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
struct amdgpu_ctx *ctx; struct amdgpu_ctx *ctx;
int i, j, r; int r;
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) if (!ctx)
return -ENOMEM; return -ENOMEM;
if (fpriv) {
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
mutex_lock(&mgr->lock); mutex_lock(&mgr->lock);
r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL); r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL);
if (r < 0) { if (r < 0) {
...@@ -80,52 +100,28 @@ int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, ...@@ -80,52 +100,28 @@ int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
return r; return r;
} }
*id = (uint32_t)r; *id = (uint32_t)r;
amdgpu_ctx_init(adev, fpriv, ctx); r = amdgpu_ctx_init(adev, false, ctx);
mutex_unlock(&mgr->lock); 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; return r;
} }
if (amdgpu_enable_scheduler) { static void amdgpu_ctx_do_release(struct kref *ref)
/* create context entity for each ring */ {
for (i = 0; i < adev->num_rings; i++) { struct amdgpu_ctx *ctx;
struct amd_run_queue *rq;
if (fpriv)
rq = &adev->rings[i]->scheduler->sched_rq;
else
rq = &adev->rings[i]->scheduler->kernel_rq;
r = amd_context_entity_init(adev->rings[i]->scheduler,
&ctx->rings[i].c_entity,
NULL, rq, amdgpu_sched_jobs);
if (r)
break;
}
if (i < adev->num_rings) { ctx = container_of(ref, struct amdgpu_ctx, refcount);
for (j = 0; j < i; j++)
amd_context_entity_fini(adev->rings[j]->scheduler,
&ctx->rings[j].c_entity);
kfree(ctx);
return -EINVAL;
}
}
return 0; amdgpu_ctx_fini(ctx);
kfree(ctx);
} }
int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id) static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id)
{ {
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
struct amdgpu_ctx *ctx; struct amdgpu_ctx *ctx;
if (fpriv) {
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
mutex_lock(&mgr->lock); mutex_lock(&mgr->lock);
ctx = idr_find(&mgr->ctx_handles, id); ctx = idr_find(&mgr->ctx_handles, id);
if (ctx) { if (ctx) {
...@@ -135,11 +131,6 @@ int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint ...@@ -135,11 +131,6 @@ int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint
return 0; return 0;
} }
mutex_unlock(&mgr->lock); mutex_unlock(&mgr->lock);
} else {
ctx = adev->kernel_ctx;
kref_put(&ctx->refcount, amdgpu_ctx_do_release);
return 0;
}
return -EINVAL; return -EINVAL;
} }
...@@ -198,7 +189,7 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, ...@@ -198,7 +189,7 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
args->out.alloc.ctx_id = id; args->out.alloc.ctx_id = id;
break; break;
case AMDGPU_CTX_OP_FREE_CTX: case AMDGPU_CTX_OP_FREE_CTX:
r = amdgpu_ctx_free(adev, fpriv, id); r = amdgpu_ctx_free(fpriv, id);
break; break;
case AMDGPU_CTX_OP_QUERY_STATE: case AMDGPU_CTX_OP_QUERY_STATE:
r = amdgpu_ctx_query(adev, fpriv, id, &args->out); r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
......
...@@ -1525,14 +1525,11 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1525,14 +1525,11 @@ int amdgpu_device_init(struct amdgpu_device *adev,
return r; return r;
} }
if (!adev->kernel_ctx) { r = amdgpu_ctx_init(adev, true, &adev->kernel_ctx);
uint32_t id = 0;
r = amdgpu_ctx_alloc(adev, NULL, &id);
if (r) { if (r) {
dev_err(adev->dev, "failed to create kernel context (%d).\n", r); dev_err(adev->dev, "failed to create kernel context (%d).\n", r);
return r; return r;
} }
}
r = amdgpu_ib_ring_tests(adev); r = amdgpu_ib_ring_tests(adev);
if (r) if (r)
DRM_ERROR("ib ring test failed (%d).\n", r); DRM_ERROR("ib ring test failed (%d).\n", r);
...@@ -1594,7 +1591,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) ...@@ -1594,7 +1591,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
adev->shutdown = true; adev->shutdown = true;
/* evict vram memory */ /* evict vram memory */
amdgpu_bo_evict_vram(adev); amdgpu_bo_evict_vram(adev);
amdgpu_ctx_free(adev, NULL, 0); amdgpu_ctx_fini(&adev->kernel_ctx);
amdgpu_ib_pool_fini(adev); amdgpu_ib_pool_fini(adev);
amdgpu_fence_driver_fini(adev); amdgpu_fence_driver_fini(adev);
amdgpu_fbdev_fini(adev); amdgpu_fbdev_fini(adev);
......
...@@ -122,19 +122,17 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, ...@@ -122,19 +122,17 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
int r = 0; int r = 0;
if (amdgpu_enable_scheduler) { if (amdgpu_enable_scheduler) {
struct amdgpu_cs_parser *sched_job = struct amdgpu_cs_parser *sched_job =
amdgpu_cs_parser_create(adev, amdgpu_cs_parser_create(adev, owner, &adev->kernel_ctx,
owner,
adev->kernel_ctx,
ibs, 1); ibs, 1);
if(!sched_job) { if(!sched_job) {
return -ENOMEM; return -ENOMEM;
} }
sched_job->free_job = free_job; sched_job->free_job = free_job;
ibs[num_ibs - 1].sequence = amd_sched_push_job(ring->scheduler, ibs[num_ibs - 1].sequence = amd_sched_push_job(ring->scheduler,
&adev->kernel_ctx->rings[ring->idx].c_entity, &adev->kernel_ctx.rings[ring->idx].c_entity,
sched_job); sched_job);
r = amd_sched_wait_emit( r = amd_sched_wait_emit(
&adev->kernel_ctx->rings[ring->idx].c_entity, &adev->kernel_ctx.rings[ring->idx].c_entity,
ibs[num_ibs - 1].sequence, false, -1); ibs[num_ibs - 1].sequence, false, -1);
if (r) if (r)
WARN(true, "emit timeout\n"); WARN(true, "emit timeout\n");
......
...@@ -372,16 +372,16 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, ...@@ -372,16 +372,16 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
if (amdgpu_enable_scheduler) { if (amdgpu_enable_scheduler) {
int r; int r;
sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
adev->kernel_ctx, ib, 1); &adev->kernel_ctx, ib, 1);
if(!sched_job) if(!sched_job)
goto error_free; goto error_free;
sched_job->job_param.vm.bo = bo; sched_job->job_param.vm.bo = bo;
sched_job->run_job = amdgpu_vm_run_job; sched_job->run_job = amdgpu_vm_run_job;
sched_job->free_job = amdgpu_vm_free_job; sched_job->free_job = amdgpu_vm_free_job;
ib->sequence = amd_sched_push_job(ring->scheduler, ib->sequence = amd_sched_push_job(ring->scheduler,
&adev->kernel_ctx->rings[ring->idx].c_entity, &adev->kernel_ctx.rings[ring->idx].c_entity,
sched_job); sched_job);
r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity, r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity,
ib->sequence, false, -1); ib->sequence, false, -1);
if (r) if (r)
DRM_ERROR("emit timeout\n"); DRM_ERROR("emit timeout\n");
...@@ -517,7 +517,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ...@@ -517,7 +517,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
if (amdgpu_enable_scheduler) { if (amdgpu_enable_scheduler) {
int r; int r;
sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
adev->kernel_ctx, &adev->kernel_ctx,
ib, 1); ib, 1);
if(!sched_job) if(!sched_job)
goto error_free; goto error_free;
...@@ -525,9 +525,9 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ...@@ -525,9 +525,9 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
sched_job->run_job = amdgpu_vm_run_job; sched_job->run_job = amdgpu_vm_run_job;
sched_job->free_job = amdgpu_vm_free_job; sched_job->free_job = amdgpu_vm_free_job;
ib->sequence = amd_sched_push_job(ring->scheduler, ib->sequence = amd_sched_push_job(ring->scheduler,
&adev->kernel_ctx->rings[ring->idx].c_entity, &adev->kernel_ctx.rings[ring->idx].c_entity,
sched_job); sched_job);
r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity, r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity,
ib->sequence, false, -1); ib->sequence, false, -1);
if (r) if (r)
DRM_ERROR("emit timeout\n"); DRM_ERROR("emit timeout\n");
...@@ -863,7 +863,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ...@@ -863,7 +863,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
if (amdgpu_enable_scheduler) { if (amdgpu_enable_scheduler) {
int r; int r;
sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
adev->kernel_ctx, ib, 1); &adev->kernel_ctx, ib, 1);
if(!sched_job) if(!sched_job)
goto error_free; goto error_free;
sched_job->job_param.vm_mapping.vm = vm; sched_job->job_param.vm_mapping.vm = vm;
...@@ -873,9 +873,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ...@@ -873,9 +873,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
sched_job->run_job = amdgpu_vm_bo_update_mapping_run_job; sched_job->run_job = amdgpu_vm_bo_update_mapping_run_job;
sched_job->free_job = amdgpu_vm_free_job; sched_job->free_job = amdgpu_vm_free_job;
ib->sequence = amd_sched_push_job(ring->scheduler, ib->sequence = amd_sched_push_job(ring->scheduler,
&adev->kernel_ctx->rings[ring->idx].c_entity, &adev->kernel_ctx.rings[ring->idx].c_entity,
sched_job); sched_job);
r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity, r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity,
ib->sequence, false, -1); ib->sequence, false, -1);
if (r) if (r)
DRM_ERROR("emit timeout\n"); DRM_ERROR("emit timeout\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment