aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0552-drm-amdgpu-more-scheduler-cleanups-v2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0552-drm-amdgpu-more-scheduler-cleanups-v2.patch')
-rw-r--r--meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0552-drm-amdgpu-more-scheduler-cleanups-v2.patch412
1 files changed, 412 insertions, 0 deletions
diff --git a/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0552-drm-amdgpu-more-scheduler-cleanups-v2.patch b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0552-drm-amdgpu-more-scheduler-cleanups-v2.patch
new file mode 100644
index 00000000..0886c37d
--- /dev/null
+++ b/meta-amdfalconx86/recipes-kernel/linux/linux-yocto/0552-drm-amdgpu-more-scheduler-cleanups-v2.patch
@@ -0,0 +1,412 @@
+From 4f839a243d3b0d8b1a14f4778a87ec4d8ddbf15f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Tue, 8 Sep 2015 20:22:31 +0200
+Subject: [PATCH 0552/1050] drm/amdgpu: more scheduler cleanups v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Embed the scheduler into the ring structure instead of allocating it.
+Use the ring name directly instead of the id.
+
+v2: rebased, whitespace cleanup
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com>
+Reviewed-by: Chunming Zhou<david1.zhou@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 +--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 10 +++---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 23 ++++++-------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 4 ++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | 43 +++++++++++++++++--------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 10 ++++--
+ drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h | 8 ++---
+ drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 37 ++++++++-------------
+ drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 20 ++++++------
+ 11 files changed, 87 insertions(+), 76 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 9108b7c..57b427f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -433,7 +433,7 @@ int amdgpu_fence_driver_init(struct amdgpu_device *adev);
+ void amdgpu_fence_driver_fini(struct amdgpu_device *adev);
+ void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev);
+
+-void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
++int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
+ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
+ struct amdgpu_irq_src *irq_src,
+ unsigned irq_type);
+@@ -891,7 +891,7 @@ struct amdgpu_ring {
+ struct amdgpu_device *adev;
+ const struct amdgpu_ring_funcs *funcs;
+ struct amdgpu_fence_driver fence_drv;
+- struct amd_gpu_scheduler *sched;
++ struct amd_gpu_scheduler sched;
+
+ spinlock_t fence_lock;
+ struct mutex *ring_lock;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index 6f39b2d..b74b6a8 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -848,7 +848,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
+ job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL);
+ if (!job)
+ return -ENOMEM;
+- job->base.sched = ring->sched;
++ job->base.sched = &ring->sched;
+ job->base.s_entity = &parser->ctx->rings[ring->idx].entity;
+ job->adev = parser->adev;
+ job->ibs = parser->ibs;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+index 5494831..e0b80cc 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+@@ -43,10 +43,10 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
+ for (i = 0; i < adev->num_rings; i++) {
+ struct amd_sched_rq *rq;
+ if (kernel)
+- rq = &adev->rings[i]->sched->kernel_rq;
++ rq = &adev->rings[i]->sched.kernel_rq;
+ else
+- rq = &adev->rings[i]->sched->sched_rq;
+- r = amd_sched_entity_init(adev->rings[i]->sched,
++ rq = &adev->rings[i]->sched.sched_rq;
++ r = amd_sched_entity_init(&adev->rings[i]->sched,
+ &ctx->rings[i].entity,
+ rq, amdgpu_sched_jobs);
+ if (r)
+@@ -55,7 +55,7 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
+
+ if (i < adev->num_rings) {
+ for (j = 0; j < i; j++)
+- amd_sched_entity_fini(adev->rings[j]->sched,
++ amd_sched_entity_fini(&adev->rings[j]->sched,
+ &ctx->rings[j].entity);
+ kfree(ctx);
+ return r;
+@@ -75,7 +75,7 @@ void amdgpu_ctx_fini(struct amdgpu_ctx *ctx)
+
+ if (amdgpu_enable_scheduler) {
+ for (i = 0; i < adev->num_rings; i++)
+- amd_sched_entity_fini(adev->rings[i]->sched,
++ amd_sched_entity_fini(&adev->rings[i]->sched,
+ &ctx->rings[i].entity);
+ }
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+index 7f2d85e..b3fc26c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+@@ -609,9 +609,9 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
+ * Init the fence driver for the requested ring (all asics).
+ * Helper function for amdgpu_fence_driver_init().
+ */
+-void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring)
++int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring)
+ {
+- int i;
++ int i, r;
+
+ ring->fence_drv.cpu_addr = NULL;
+ ring->fence_drv.gpu_addr = 0;
+@@ -628,14 +628,16 @@ void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring)
+ init_waitqueue_head(&ring->fence_drv.fence_queue);
+
+ if (amdgpu_enable_scheduler) {
+- ring->sched = amd_sched_create(&amdgpu_sched_ops,
+- ring->idx,
+- amdgpu_sched_hw_submission,
+- (void *)ring->adev);
+- if (!ring->sched)
+- DRM_ERROR("Failed to create scheduler on ring %d.\n",
+- ring->idx);
++ r = amd_sched_init(&ring->sched, &amdgpu_sched_ops,
++ amdgpu_sched_hw_submission, ring->name);
++ if (r) {
++ DRM_ERROR("Failed to create scheduler on ring %s.\n",
++ ring->name);
++ return r;
++ }
+ }
++
++ return 0;
+ }
+
+ /**
+@@ -683,8 +685,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
+ wake_up_all(&ring->fence_drv.fence_queue);
+ amdgpu_irq_put(adev, ring->fence_drv.irq_src,
+ ring->fence_drv.irq_type);
+- if (ring->sched)
+- amd_sched_destroy(ring->sched);
++ amd_sched_fini(&ring->sched);
+ ring->fence_drv.initialized = false;
+ }
+ mutex_unlock(&adev->ring_lock);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+index 6e73543..30dce23 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+@@ -357,7 +357,9 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
+ ring->adev = adev;
+ ring->idx = adev->num_rings++;
+ adev->rings[ring->idx] = ring;
+- amdgpu_fence_driver_init_ring(ring);
++ r = amdgpu_fence_driver_init_ring(ring);
++ if (r)
++ return r;
+ }
+
+ r = amdgpu_wb_get(adev, &ring->rptr_offs);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+index 7cf5405..e907124 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+@@ -145,8 +145,13 @@ static uint32_t amdgpu_sa_get_ring_from_fence(struct fence *f)
+ struct amd_sched_fence *s_fence;
+
+ s_fence = to_amd_sched_fence(f);
+- if (s_fence)
+- return s_fence->sched->ring_id;
++ if (s_fence) {
++ struct amdgpu_ring *ring;
++
++ ring = container_of(s_fence->sched, struct amdgpu_ring, sched);
++ return ring->idx;
++ }
++
+ a_fence = to_amdgpu_fence(f);
+ if (a_fence)
+ return a_fence->ring->idx;
+@@ -412,6 +417,26 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct amdgpu_sa_bo **sa_bo,
+ }
+
+ #if defined(CONFIG_DEBUG_FS)
++
++static void amdgpu_sa_bo_dump_fence(struct fence *fence, struct seq_file *m)
++{
++ struct amdgpu_fence *a_fence = to_amdgpu_fence(fence);
++ struct amd_sched_fence *s_fence = to_amd_sched_fence(fence);
++
++ if (a_fence)
++ seq_printf(m, " protected by 0x%016llx on ring %d",
++ a_fence->seq, a_fence->ring->idx);
++
++ if (s_fence) {
++ struct amdgpu_ring *ring;
++
++
++ ring = container_of(s_fence->sched, struct amdgpu_ring, sched);
++ seq_printf(m, " protected by 0x%016x on ring %d",
++ s_fence->base.seqno, ring->idx);
++ }
++}
++
+ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
+ struct seq_file *m)
+ {
+@@ -428,18 +453,8 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
+ }
+ seq_printf(m, "[0x%010llx 0x%010llx] size %8lld",
+ soffset, eoffset, eoffset - soffset);
+- if (i->fence) {
+- struct amdgpu_fence *a_fence = to_amdgpu_fence(i->fence);
+- struct amd_sched_fence *s_fence = to_amd_sched_fence(i->fence);
+- if (a_fence)
+- seq_printf(m, " protected by 0x%016llx on ring %d",
+- a_fence->seq, a_fence->ring->idx);
+- if (s_fence)
+- seq_printf(m, " protected by 0x%016x on ring %d",
+- s_fence->base.seqno,
+- s_fence->sched->ring_id);
+-
+- }
++ if (i->fence)
++ amdgpu_sa_bo_dump_fence(i->fence, m);
+ seq_printf(m, "\n");
+ }
+ spin_unlock(&sa_manager->wq.lock);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
+index d1984fc..2e946b2 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
+@@ -85,7 +85,7 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
+ kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL);
+ if (!job)
+ return -ENOMEM;
+- job->base.sched = ring->sched;
++ job->base.sched = &ring->sched;
+ job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity;
+ job->adev = adev;
+ job->ibs = ibs;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+index b57ca10..4921de1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+@@ -65,8 +65,14 @@ static bool amdgpu_sync_same_dev(struct amdgpu_device *adev, struct fence *f)
+
+ if (a_fence)
+ return a_fence->ring->adev == adev;
+- if (s_fence)
+- return (struct amdgpu_device *)s_fence->sched->priv == adev;
++
++ if (s_fence) {
++ struct amdgpu_ring *ring;
++
++ ring = container_of(s_fence->sched, struct amdgpu_ring, sched);
++ return ring->adev == adev;
++ }
++
+ return false;
+ }
+
+diff --git a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
+index a1f4ece..144f50a 100644
+--- a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
++++ b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
+@@ -16,21 +16,21 @@ TRACE_EVENT(amd_sched_job,
+ TP_ARGS(sched_job),
+ TP_STRUCT__entry(
+ __field(struct amd_sched_entity *, entity)
+- __field(u32, ring_id)
++ __field(const char *, name)
+ __field(u32, job_count)
+ __field(int, hw_job_count)
+ ),
+
+ TP_fast_assign(
+ __entry->entity = sched_job->s_entity;
+- __entry->ring_id = sched_job->sched->ring_id;
++ __entry->name = sched_job->sched->name;
+ __entry->job_count = kfifo_len(
+ &sched_job->s_entity->job_queue) / sizeof(sched_job);
+ __entry->hw_job_count = atomic_read(
+ &sched_job->sched->hw_rq_count);
+ ),
+- TP_printk("entity=%p, ring=%u, job count:%u, hw job count:%d",
+- __entry->entity, __entry->ring_id, __entry->job_count,
++ TP_printk("entity=%p, ring=%s, job count:%u, hw job count:%d",
++ __entry->entity, __entry->name, __entry->job_count,
+ __entry->hw_job_count)
+ );
+ #endif
+diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+index ec4842e..3697eee 100644
+--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
++++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+@@ -381,56 +381,45 @@ static int amd_sched_main(void *param)
+ }
+
+ /**
+- * Create a gpu scheduler
++ * Init a gpu scheduler instance
+ *
++ * @sched The pointer to the scheduler
+ * @ops The backend operations for this scheduler.
+- * @ring The the ring id for the scheduler.
+ * @hw_submissions Number of hw submissions to do.
++ * @name Name used for debugging
+ *
+- * Return the pointer to scheduler for success, otherwise return NULL
++ * Return 0 on success, otherwise error code.
+ */
+-struct amd_gpu_scheduler *amd_sched_create(struct amd_sched_backend_ops *ops,
+- unsigned ring, unsigned hw_submission,
+- void *priv)
++int amd_sched_init(struct amd_gpu_scheduler *sched,
++ struct amd_sched_backend_ops *ops,
++ unsigned hw_submission, const char *name)
+ {
+- struct amd_gpu_scheduler *sched;
+-
+- sched = kzalloc(sizeof(struct amd_gpu_scheduler), GFP_KERNEL);
+- if (!sched)
+- return NULL;
+-
+ sched->ops = ops;
+- sched->ring_id = ring;
+ sched->hw_submission_limit = hw_submission;
+- sched->priv = priv;
+- snprintf(sched->name, sizeof(sched->name), "amdgpu[%d]", ring);
++ sched->name = name;
+ amd_sched_rq_init(&sched->sched_rq);
+ amd_sched_rq_init(&sched->kernel_rq);
+
+ init_waitqueue_head(&sched->wake_up_worker);
+ init_waitqueue_head(&sched->job_scheduled);
+ atomic_set(&sched->hw_rq_count, 0);
++
+ /* Each scheduler will run on a seperate kernel thread */
+ sched->thread = kthread_run(amd_sched_main, sched, sched->name);
+ if (IS_ERR(sched->thread)) {
+- DRM_ERROR("Failed to create scheduler for id %d.\n", ring);
+- kfree(sched);
+- return NULL;
++ DRM_ERROR("Failed to create scheduler for %s.\n", name);
++ return PTR_ERR(sched->thread);
+ }
+
+- return sched;
++ return 0;
+ }
+
+ /**
+ * Destroy a gpu scheduler
+ *
+ * @sched The pointer to the scheduler
+- *
+- * return 0 if succeed. -1 if failed.
+ */
+-int amd_sched_destroy(struct amd_gpu_scheduler *sched)
++void amd_sched_fini(struct amd_gpu_scheduler *sched)
+ {
+ kthread_stop(sched->thread);
+- kfree(sched);
+- return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+index 89d977d..80b64dc 100644
+--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
++++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+@@ -101,23 +101,21 @@ struct amd_sched_backend_ops {
+ * One scheduler is implemented for each hardware ring
+ */
+ struct amd_gpu_scheduler {
+- struct task_struct *thread;
++ struct amd_sched_backend_ops *ops;
++ uint32_t hw_submission_limit;
++ const char *name;
+ struct amd_sched_rq sched_rq;
+ struct amd_sched_rq kernel_rq;
+- atomic_t hw_rq_count;
+- struct amd_sched_backend_ops *ops;
+- uint32_t ring_id;
+ wait_queue_head_t wake_up_worker;
+ wait_queue_head_t job_scheduled;
+- uint32_t hw_submission_limit;
+- char name[20];
+- void *priv;
++ atomic_t hw_rq_count;
++ struct task_struct *thread;
+ };
+
+-struct amd_gpu_scheduler *
+-amd_sched_create(struct amd_sched_backend_ops *ops,
+- uint32_t ring, uint32_t hw_submission, void *priv);
+-int amd_sched_destroy(struct amd_gpu_scheduler *sched);
++int amd_sched_init(struct amd_gpu_scheduler *sched,
++ struct amd_sched_backend_ops *ops,
++ uint32_t hw_submission, const char *name);
++void amd_sched_fini(struct amd_gpu_scheduler *sched);
+
+ int amd_sched_entity_init(struct amd_gpu_scheduler *sched,
+ struct amd_sched_entity *entity,
+--
+1.9.1
+