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)
This commit is contained in:
parent
0e89d0c16b
commit
47f38501f1
|
@ -1033,10 +1033,9 @@ struct amdgpu_ctx_mgr {
|
|||
struct idr ctx_handles;
|
||||
};
|
||||
|
||||
int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
|
||||
uint32_t *id);
|
||||
int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
|
||||
uint32_t id);
|
||||
int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
|
||||
struct amdgpu_ctx *ctx);
|
||||
void amdgpu_ctx_fini(struct amdgpu_ctx *ctx);
|
||||
|
||||
struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id);
|
||||
int amdgpu_ctx_put(struct amdgpu_ctx *ctx);
|
||||
|
@ -2095,7 +2094,7 @@ struct amdgpu_device {
|
|||
struct kfd_dev *kfd;
|
||||
|
||||
/* kernel conext for IB submission */
|
||||
struct amdgpu_ctx *kernel_ctx;
|
||||
struct amdgpu_ctx kernel_ctx;
|
||||
};
|
||||
|
||||
bool amdgpu_device_is_px(struct drm_device *dev);
|
||||
|
|
|
@ -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;
|
||||
|
||||
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);
|
||||
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;
|
||||
|
||||
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;
|
||||
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);
|
||||
|
|
|
@ -1525,13 +1525,10 @@ 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_ctx_init(adev, true, &adev->kernel_ctx);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed to create kernel context (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_ib_ring_tests(adev);
|
||||
if (r)
|
||||
|
@ -1594,7 +1591,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_ctx_fini(&adev->kernel_ctx);
|
||||
amdgpu_ib_pool_fini(adev);
|
||||
amdgpu_fence_driver_fini(adev);
|
||||
amdgpu_fbdev_fini(adev);
|
||||
|
|
|
@ -122,19 +122,17 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
|
|||
int r = 0;
|
||||
if (amdgpu_enable_scheduler) {
|
||||
struct amdgpu_cs_parser *sched_job =
|
||||
amdgpu_cs_parser_create(adev,
|
||||
owner,
|
||||
adev->kernel_ctx,
|
||||
amdgpu_cs_parser_create(adev, owner, &adev->kernel_ctx,
|
||||
ibs, 1);
|
||||
if(!sched_job) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
sched_job->free_job = free_job;
|
||||
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);
|
||||
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);
|
||||
if (r)
|
||||
WARN(true, "emit timeout\n");
|
||||
|
|
|
@ -372,16 +372,16 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
|
|||
if (amdgpu_enable_scheduler) {
|
||||
int r;
|
||||
sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
|
||||
adev->kernel_ctx, ib, 1);
|
||||
&adev->kernel_ctx, ib, 1);
|
||||
if(!sched_job)
|
||||
goto error_free;
|
||||
sched_job->job_param.vm.bo = bo;
|
||||
sched_job->run_job = amdgpu_vm_run_job;
|
||||
sched_job->free_job = amdgpu_vm_free_job;
|
||||
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);
|
||||
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);
|
||||
if (r)
|
||||
DRM_ERROR("emit timeout\n");
|
||||
|
@ -517,7 +517,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
|
|||
if (amdgpu_enable_scheduler) {
|
||||
int r;
|
||||
sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
|
||||
adev->kernel_ctx,
|
||||
&adev->kernel_ctx,
|
||||
ib, 1);
|
||||
if(!sched_job)
|
||||
goto error_free;
|
||||
|
@ -525,9 +525,9 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
|
|||
sched_job->run_job = amdgpu_vm_run_job;
|
||||
sched_job->free_job = amdgpu_vm_free_job;
|
||||
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);
|
||||
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);
|
||||
if (r)
|
||||
DRM_ERROR("emit timeout\n");
|
||||
|
@ -863,7 +863,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||
if (amdgpu_enable_scheduler) {
|
||||
int r;
|
||||
sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
|
||||
adev->kernel_ctx, ib, 1);
|
||||
&adev->kernel_ctx, ib, 1);
|
||||
if(!sched_job)
|
||||
goto error_free;
|
||||
sched_job->job_param.vm_mapping.vm = vm;
|
||||
|
@ -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->free_job = amdgpu_vm_free_job;
|
||||
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);
|
||||
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);
|
||||
if (r)
|
||||
DRM_ERROR("emit timeout\n");
|
||||
|
|
Loading…
Reference in New Issue