diff options
author | Dave Airlie <airlied@redhat.com> | 2015-10-16 09:39:14 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-10-16 09:39:14 +1000 |
commit | aa1b36f2bb068e6d76b0bef2da286631bfa1bff1 (patch) | |
tree | c4acebfa46b13e556ec47fbbf3fa0697e50660cf /drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | |
parent | 99a91c94972d1d583beb4b4854f55984f7cc2dc8 (diff) | |
parent | 2fcef6ec87a044221fc3c2f16873f7c02b9ae991 (diff) | |
download | linux-aa1b36f2bb068e6d76b0bef2da286631bfa1bff1.tar.bz2 |
Merge branch 'drm-next-4.4' of git://people.freedesktop.org/~agd5f/linux into drm-next
This is the first radeon and amdgpu pull for drm-next. Highlights include:
- Efficiency improvements to the CS checker for pre-SI asics
- Cursor fixes ported from radeon to amdgpu
- Enable GPU scheduler by default
- Add a bunch of GPUVM debugging options
- Add support for some new atombios opcodes
- Misc cleanups and fixes
* 'drm-next-4.4' of git://people.freedesktop.org/~agd5f/linux: (42 commits)
drm/amdgpu: fix lockup when clean pending fences
drm/amdgpu: add timer to fence to detect scheduler lockup
drm/amdgpu: add VM CS mapping trace point
drm/amdgpu: add option to clear VM page tables after every submit
drm/amdgpu: add option to stop on VM fault
drm/amdgpu: only print meaningful VM faults
drm/amdgpu: also trace already allocated VMIDs
drm/amdgpu: Drop unnecessary #include <linux/vga_switcheroo.h>
drm/radeon: Drop unnecessary #include <linux/vga_switcheroo.h>
drm/amdgpu: clean up pageflip interrupt handling
drm/amdgpu: rework sdma structures
drm/amdgpu: unpin cursor BOs on suspend and pin them again on resume
drm/amdgpu/dce8: Fold set_cursor() into show_cursor()
drm/amdgpu/dce8: Clean up reference counting and pinning of the cursor BOs
drm/amdgpu/dce8: Move hotspot handling out of set_cursor
drm/amdgpu/dce8: Re-show the cursor after a modeset (v2)
drm/amdgpu/dce8: Use cursor_set2 hook for enabling / disabling the HW cursor
drm/amdgpu/dce11: Fold set_cursor() into show_cursor()
drm/amdgpu/dce11: Clean up reference counting and pinning of the cursor BOs
drm/amdgpu/dce11: Move hotspot handling out of set_cursor
...
Diffstat (limited to 'drivers/gpu/drm/amd/scheduler/gpu_scheduler.c')
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 3697eeeecf82..7fa1d7a438e9 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -327,19 +327,49 @@ static void amd_sched_process_job(struct fence *f, struct fence_cb *cb) struct amd_sched_fence *s_fence = container_of(cb, struct amd_sched_fence, cb); struct amd_gpu_scheduler *sched = s_fence->sched; + unsigned long flags; atomic_dec(&sched->hw_rq_count); amd_sched_fence_signal(s_fence); + if (sched->timeout != MAX_SCHEDULE_TIMEOUT) { + cancel_delayed_work_sync(&s_fence->dwork); + spin_lock_irqsave(&sched->fence_list_lock, flags); + list_del_init(&s_fence->list); + spin_unlock_irqrestore(&sched->fence_list_lock, flags); + } fence_put(&s_fence->base); wake_up_interruptible(&sched->wake_up_worker); } +static void amd_sched_fence_work_func(struct work_struct *work) +{ + struct amd_sched_fence *s_fence = + container_of(work, struct amd_sched_fence, dwork.work); + struct amd_gpu_scheduler *sched = s_fence->sched; + struct amd_sched_fence *entity, *tmp; + unsigned long flags; + + DRM_ERROR("[%s] scheduler is timeout!\n", sched->name); + + /* Clean all pending fences */ + spin_lock_irqsave(&sched->fence_list_lock, flags); + list_for_each_entry_safe(entity, tmp, &sched->fence_list, list) { + DRM_ERROR(" fence no %d\n", entity->base.seqno); + cancel_delayed_work(&entity->dwork); + list_del_init(&entity->list); + fence_put(&entity->base); + } + spin_unlock_irqrestore(&sched->fence_list_lock, flags); +} + static int amd_sched_main(void *param) { struct sched_param sparam = {.sched_priority = 1}; struct amd_gpu_scheduler *sched = (struct amd_gpu_scheduler *)param; int r, count; + spin_lock_init(&sched->fence_list_lock); + INIT_LIST_HEAD(&sched->fence_list); sched_setscheduler(current, SCHED_FIFO, &sparam); while (!kthread_should_stop()) { @@ -347,6 +377,7 @@ static int amd_sched_main(void *param) struct amd_sched_fence *s_fence; struct amd_sched_job *sched_job; struct fence *fence; + unsigned long flags; wait_event_interruptible(sched->wake_up_worker, kthread_should_stop() || @@ -357,6 +388,15 @@ static int amd_sched_main(void *param) entity = sched_job->s_entity; s_fence = sched_job->s_fence; + + if (sched->timeout != MAX_SCHEDULE_TIMEOUT) { + INIT_DELAYED_WORK(&s_fence->dwork, amd_sched_fence_work_func); + schedule_delayed_work(&s_fence->dwork, sched->timeout); + spin_lock_irqsave(&sched->fence_list_lock, flags); + list_add_tail(&s_fence->list, &sched->fence_list); + spin_unlock_irqrestore(&sched->fence_list_lock, flags); + } + atomic_inc(&sched->hw_rq_count); fence = sched->ops->run_job(sched_job); if (fence) { @@ -392,11 +432,12 @@ static int amd_sched_main(void *param) */ int amd_sched_init(struct amd_gpu_scheduler *sched, struct amd_sched_backend_ops *ops, - unsigned hw_submission, const char *name) + unsigned hw_submission, long timeout, const char *name) { sched->ops = ops; sched->hw_submission_limit = hw_submission; sched->name = name; + sched->timeout = timeout; amd_sched_rq_init(&sched->sched_rq); amd_sched_rq_init(&sched->kernel_rq); |