From d033a6de80054139b4358db12cf6bb8d6cf58853 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Thu, 5 Nov 2015 15:23:09 +0800 Subject: drm/amd: abstract kernel rq and normal rq to priority of run queue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows us to set priorities in the scheduler. Signed-off-by: Chunming Zhou Reviewed-by: Christian König Reviewed-by: Junwei Zhang --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index fec65f01c031..c1f2308b4115 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -25,7 +25,7 @@ #include #include "amdgpu.h" -int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel, +int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri, struct amdgpu_ctx *ctx) { unsigned i, j; @@ -42,10 +42,9 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel, /* create context entity for each ring */ for (i = 0; i < adev->num_rings; i++) { struct amd_sched_rq *rq; - if (kernel) - rq = &adev->rings[i]->sched.kernel_rq; - else - rq = &adev->rings[i]->sched.sched_rq; + if (pri >= AMD_SCHED_MAX_PRIORITY) + return -EINVAL; + rq = &adev->rings[i]->sched.sched_rq[pri]; r = amd_sched_entity_init(&adev->rings[i]->sched, &ctx->rings[i].entity, rq, amdgpu_sched_jobs); @@ -103,7 +102,7 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev, return r; } *id = (uint32_t)r; - r = amdgpu_ctx_init(adev, false, ctx); + r = amdgpu_ctx_init(adev, AMD_SCHED_PRIORITY_NORMAL, ctx); mutex_unlock(&mgr->lock); return r; -- cgit From c648ed7c5c7f0e3bb4ab11bf08bccf99b42a4cbb Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Thu, 10 Dec 2015 15:50:02 +0800 Subject: drm/amdgpu: handle error case for ctx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Properly handle ctx init failure. Signed-off-by: Chunming Zhou Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index c1f2308b4115..15e341634536 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -56,7 +56,6 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri, for (j = 0; j < i; j++) amd_sched_entity_fini(&adev->rings[j]->sched, &ctx->rings[j].entity); - kfree(ctx); return r; } } @@ -103,8 +102,12 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev, } *id = (uint32_t)r; r = amdgpu_ctx_init(adev, AMD_SCHED_PRIORITY_NORMAL, ctx); + if (r) { + idr_remove(&mgr->ctx_handles, *id); + *id = 0; + kfree(ctx); + } mutex_unlock(&mgr->lock); - return r; } -- cgit From 37cd0ca204a55e123fca9ce411e6571ac49fa8f7 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Thu, 10 Dec 2015 15:45:11 +0800 Subject: drm/amdgpu: unify AMDGPU_CTX_MAX_CS_PENDING and amdgpu_sched_jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Chunming Zhou Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 5 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 25 ++++++++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 3b5d3706f0cb..c3996e0e2e7e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1023,11 +1023,9 @@ int amdgpu_vm_free_job(struct amdgpu_job *job); * context related structures */ -#define AMDGPU_CTX_MAX_CS_PENDING 16 - struct amdgpu_ctx_ring { uint64_t sequence; - struct fence *fences[AMDGPU_CTX_MAX_CS_PENDING]; + struct fence **fences; struct amd_sched_entity entity; }; @@ -1036,6 +1034,7 @@ struct amdgpu_ctx { struct amdgpu_device *adev; unsigned reset_counter; spinlock_t ring_lock; + struct fence **fences; struct amdgpu_ctx_ring rings[AMDGPU_MAX_RINGS]; }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 15e341634536..ee121ec2917b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -35,15 +35,24 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri, 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; + ctx->fences = kzalloc(sizeof(struct fence *) * amdgpu_sched_jobs * + AMDGPU_MAX_RINGS, GFP_KERNEL); + if (!ctx->fences) + return -ENOMEM; + for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + ctx->rings[i].sequence = 1; + ctx->rings[i].fences = (void *)ctx->fences + sizeof(struct fence *) * + amdgpu_sched_jobs * i; + } if (amdgpu_enable_scheduler) { /* create context entity for each ring */ for (i = 0; i < adev->num_rings; i++) { struct amd_sched_rq *rq; - if (pri >= AMD_SCHED_MAX_PRIORITY) + if (pri >= AMD_SCHED_MAX_PRIORITY) { + kfree(ctx->fences); return -EINVAL; + } rq = &adev->rings[i]->sched.sched_rq[pri]; r = amd_sched_entity_init(&adev->rings[i]->sched, &ctx->rings[i].entity, @@ -56,6 +65,7 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri, for (j = 0; j < i; j++) amd_sched_entity_fini(&adev->rings[j]->sched, &ctx->rings[j].entity); + kfree(ctx->fences); return r; } } @@ -71,8 +81,9 @@ void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) return; for (i = 0; i < AMDGPU_MAX_RINGS; ++i) - for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j) + for (j = 0; j < amdgpu_sched_jobs; ++j) fence_put(ctx->rings[i].fences[j]); + kfree(ctx->fences); if (amdgpu_enable_scheduler) { for (i = 0; i < adev->num_rings; i++) @@ -241,7 +252,7 @@ uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, unsigned idx = 0; struct fence *other = NULL; - idx = seq % AMDGPU_CTX_MAX_CS_PENDING; + idx = seq % amdgpu_sched_jobs; other = cring->fences[idx]; if (other) { signed long r; @@ -276,12 +287,12 @@ struct fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, } - if (seq + AMDGPU_CTX_MAX_CS_PENDING < cring->sequence) { + if (seq + amdgpu_sched_jobs < cring->sequence) { spin_unlock(&ctx->ring_lock); return NULL; } - fence = fence_get(cring->fences[seq % AMDGPU_CTX_MAX_CS_PENDING]); + fence = fence_get(cring->fences[seq % amdgpu_sched_jobs]); spin_unlock(&ctx->ring_lock); return fence; -- cgit From 5b0112356cf9a735632b26ff5f3450e1716c8598 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Thu, 10 Dec 2015 17:34:33 +0800 Subject: drm/amdgpu: restrict the sched jobs number to power of two MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Chunming Zhou Reviewed-by: Christian König CC: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index ee121ec2917b..17d1fb12128a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -252,7 +252,7 @@ uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, unsigned idx = 0; struct fence *other = NULL; - idx = seq % amdgpu_sched_jobs; + idx = seq & (amdgpu_sched_jobs - 1); other = cring->fences[idx]; if (other) { signed long r; @@ -292,7 +292,7 @@ struct fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, return NULL; } - fence = fence_get(cring->fences[seq % amdgpu_sched_jobs]); + fence = fence_get(cring->fences[seq & (amdgpu_sched_jobs - 1)]); spin_unlock(&ctx->ring_lock); return fence; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 54af6ce7901f..587ff7145361 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -949,6 +949,15 @@ static bool amdgpu_check_pot_argument(int arg) */ static void amdgpu_check_arguments(struct amdgpu_device *adev) { + if (amdgpu_sched_jobs < 4) { + dev_warn(adev->dev, "sched jobs (%d) must be at least 4\n", + amdgpu_sched_jobs); + amdgpu_sched_jobs = 4; + } else if (!amdgpu_check_pot_argument(amdgpu_sched_jobs)){ + dev_warn(adev->dev, "sched jobs (%d) must be a power of 2\n", + amdgpu_sched_jobs); + amdgpu_sched_jobs = roundup_pow_of_two(amdgpu_sched_jobs); + } /* vramlimit must be a power of two */ if (!amdgpu_check_pot_argument(amdgpu_vram_limit)) { dev_warn(adev->dev, "vram limit (%d) must be a power of 2\n", -- cgit