From: Chunming Zhou Date: Sun, 12 Jun 2016 07:41:58 +0000 (+0800) Subject: drm/amdgpu: block scheduler when gpu reset X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=0875dc9e80eb3b01406b21947c140265527488ba;p=linux-beck.git drm/amdgpu: block scheduler when gpu reset Signed-off-by: Chunming Zhou Reviewed-by: Christian König Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ae801e9cec94..a7a84286a06f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -25,6 +25,7 @@ * Alex Deucher * Jerome Glisse */ +#include #include #include #include @@ -1895,6 +1896,14 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) atomic_inc(&adev->gpu_reset_counter); + /* block scheduler */ + for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + struct amdgpu_ring *ring = adev->rings[i]; + + if (!ring) + continue; + kthread_park(ring->sched.thread); + } /* block TTM */ resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); @@ -1928,7 +1937,7 @@ retry: struct amdgpu_ring *ring = adev->rings[i]; if (!ring) continue; - + kthread_unpark(ring->sched.thread); amdgpu_ring_restore(ring, ring_sizes[i], ring_data[i]); ring_sizes[i] = 0; ring_data[i] = NULL; @@ -1946,8 +1955,10 @@ retry: } else { amdgpu_fence_driver_force_completion(adev); for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { - if (adev->rings[i]) + if (adev->rings[i]) { + kthread_unpark(adev->rings[i]->sched.thread); kfree(ring_data[i]); + } } } diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index b1d49c5d8e44..60f58f76a1eb 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -476,6 +476,16 @@ static void amd_sched_process_job(struct fence *f, struct fence_cb *cb) wake_up_interruptible(&sched->wake_up_worker); } +static bool amd_sched_blocked(struct amd_gpu_scheduler *sched) +{ + if (kthread_should_park()) { + kthread_parkme(); + return true; + } + + return false; +} + static int amd_sched_main(void *param) { struct sched_param sparam = {.sched_priority = 1}; @@ -485,14 +495,15 @@ static int amd_sched_main(void *param) sched_setscheduler(current, SCHED_FIFO, &sparam); while (!kthread_should_stop()) { - struct amd_sched_entity *entity; + struct amd_sched_entity *entity = NULL; struct amd_sched_fence *s_fence; struct amd_sched_job *sched_job; struct fence *fence; wait_event_interruptible(sched->wake_up_worker, - (entity = amd_sched_select_entity(sched)) || - kthread_should_stop()); + (!amd_sched_blocked(sched) && + (entity = amd_sched_select_entity(sched))) || + kthread_should_stop()); if (!entity) continue;