diff options
author | Christian König <christian.koenig@amd.com> | 2015-08-05 21:22:10 +0200 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-08-17 16:51:05 -0400 |
commit | 6f0e54a964932d3d5252ac1ff7ab153c984a5d51 (patch) | |
tree | b76540873ccdb18a92e9369943466ba9d8ca67ec /drivers/gpu/drm/amd/scheduler | |
parent | 91404fb20825418fd9ab8e6533bc336e1ffc748e (diff) |
drm/amdgpu: cleanup and fix scheduler fence handling v2
v2: rebased
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v1)
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/scheduler')
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 61 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 7 |
2 files changed, 36 insertions, 32 deletions
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index eb3b0993a8cd..438dc23f4bb3 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -175,9 +175,9 @@ exit: * return 0 if succeed. negative error code on failure */ int amd_sched_entity_init(struct amd_gpu_scheduler *sched, - struct amd_sched_entity *entity, - struct amd_run_queue *rq, - uint32_t jobs) + struct amd_sched_entity *entity, + struct amd_run_queue *rq, + uint32_t jobs) { uint64_t seq_ring = 0; @@ -353,6 +353,24 @@ int amd_sched_wait_emit(struct amd_sched_entity *c_entity, return 0; } +static void amd_sched_process_job(struct fence *f, struct fence_cb *cb) +{ + struct amd_sched_job *sched_job = + container_of(cb, struct amd_sched_job, cb); + struct amd_gpu_scheduler *sched; + unsigned long flags; + + sched = sched_job->sched; + spin_lock_irqsave(&sched->queue_lock, flags); + list_del(&sched_job->list); + atomic64_dec(&sched->hw_rq_count); + spin_unlock_irqrestore(&sched->queue_lock, flags); + + sched->ops->process_job(sched, sched_job->job); + kfree(sched_job); + wake_up_interruptible(&sched->wait_queue); +} + static int amd_sched_main(void *param) { int r; @@ -365,6 +383,8 @@ static int amd_sched_main(void *param) while (!kthread_should_stop()) { struct amd_sched_job *sched_job = NULL; + struct fence *fence; + wait_event_interruptible(sched->wait_queue, is_scheduler_ready(sched) && (c_entity = select_context(sched))); @@ -388,37 +408,22 @@ static int amd_sched_main(void *param) spin_unlock_irqrestore(&sched->queue_lock, flags); } mutex_lock(&sched->sched_lock); - sched->ops->run_job(sched, c_entity, sched_job); + fence = sched->ops->run_job(sched, c_entity, sched_job); + if (fence) { + r = fence_add_callback(fence, &sched_job->cb, + amd_sched_process_job); + if (r == -ENOENT) + amd_sched_process_job(fence, &sched_job->cb); + else if (r) + DRM_ERROR("fence add callback failed (%d)\n", r); + fence_put(fence); + } mutex_unlock(&sched->sched_lock); } return 0; } /** - * ISR to handle EOP inetrrupts - * - * @sched: gpu scheduler - * -*/ -void amd_sched_process_job(struct amd_sched_job *sched_job) -{ - unsigned long flags; - struct amd_gpu_scheduler *sched; - - if (!sched_job) - return; - sched = sched_job->sched; - spin_lock_irqsave(&sched->queue_lock, flags); - list_del(&sched_job->list); - atomic64_dec(&sched->hw_rq_count); - spin_unlock_irqrestore(&sched->queue_lock, flags); - - sched->ops->process_job(sched, sched_job->job); - kfree(sched_job); - wake_up_interruptible(&sched->wait_queue); -} - -/** * Create a gpu scheduler * * @device The device context for this scheduler diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index a3e29df957fc..e7cc40a6993b 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h @@ -87,9 +87,9 @@ struct amd_sched_backend_ops { int (*prepare_job)(struct amd_gpu_scheduler *sched, struct amd_sched_entity *c_entity, void *job); - void (*run_job)(struct amd_gpu_scheduler *sched, - struct amd_sched_entity *c_entity, - struct amd_sched_job *job); + struct fence *(*run_job)(struct amd_gpu_scheduler *sched, + struct amd_sched_entity *c_entity, + struct amd_sched_job *job); void (*process_job)(struct amd_gpu_scheduler *sched, void *job); }; @@ -132,7 +132,6 @@ int amd_sched_wait_emit(struct amd_sched_entity *c_entity, bool intr, long timeout); -void amd_sched_process_job(struct amd_sched_job *sched_job); uint64_t amd_sched_get_handled_seq(struct amd_gpu_scheduler *sched); int amd_sched_entity_init(struct amd_gpu_scheduler *sched, |