aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0433-drm-amdgpu-cleanup-amdgpu_ctx-inti-fini-v2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0433-drm-amdgpu-cleanup-amdgpu_ctx-inti-fini-v2.patch')
-rw-r--r--common/recipes-kernel/linux/files/0433-drm-amdgpu-cleanup-amdgpu_ctx-inti-fini-v2.patch373
1 files changed, 373 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0433-drm-amdgpu-cleanup-amdgpu_ctx-inti-fini-v2.patch b/common/recipes-kernel/linux/files/0433-drm-amdgpu-cleanup-amdgpu_ctx-inti-fini-v2.patch
new file mode 100644
index 00000000..f62b8122
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0433-drm-amdgpu-cleanup-amdgpu_ctx-inti-fini-v2.patch
@@ -0,0 +1,373 @@
+From 47f38501f11fa45d8a7797f1965448c1e20049d4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Tue, 4 Aug 2015 17:51:05 +0200
+Subject: [PATCH 0433/1050] drm/amdgpu: cleanup amdgpu_ctx inti/fini v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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)
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 9 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 145 ++++++++++++++---------------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 13 +--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 8 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 18 ++--
+ 5 files changed, 89 insertions(+), 104 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 0cd776a..53d70f7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -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);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+index c2290ae..08a9292 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);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 801ebfc..42d1a22 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -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);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
+index 9f2f19c..995901b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
+@@ -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");
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index ab9c65a..78713ae 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -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");
+--
+1.9.1
+