drm/msm: Move hangcheck timer restart
Subsystems (4)
PATCH 1/2 drm/msm: Move hangcheck timer restart
From: Rob Clark <[email protected]>
Don't directly restart the hangcheck timer from the timer handler, but instead start it after the recover_worker replays remaining jobs.
If the kthread is blocked for other reasons, there is no point to immediately restart the timer. Fixes a random symptom of the problem fixed in the next patch.
--- drivers/gpu/drm/msm/msm_gpu.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/gpu/drm/msm/msm_gpu.c +9 -5
@@ -328,6 +328,7 @@ find_submit(struct msm_ringbuffer *ring, uint32_t fence) }static void retire_submits (struct msm_gpu *gpu); +static void hangcheck_timer_reset (struct msm_gpu *gpu);static void get_comm_cmdline (struct msm_gem_submit *submit,char **comm,char **cmd) {
@@ -420,6 +421,8 @@ static void recover_worker(struct kthread_work *work) }if (msm_gpu_active (gpu)) { +bool restart_hangcheck = false; +/* retire completed submits, plus the one that hung: */ retire_submits (gpu);
@@ -436,10 +439,15 @@ static void recover_worker(struct kthread_work *work)unsigned long flags;spin_lock_irqsave (&ring->submit_lock, flags); -list_for_each_entry (submit, &ring->submits, node) +list_for_each_entry (submit, &ring->submits, node) { gpu->funcs->submit (gpu, submit); + restart_hangcheck = true; + }spin_unlock_irqrestore (&ring->submit_lock, flags); } + +if (restart_hangcheck) +hangcheck_timer_reset (gpu); }mutex_unlock (&gpu->lock);
@@ -515,10 +523,6 @@ static void hangcheck_handler(struct timer_list *t)kthread_queue_work (gpu->worker, &gpu->recover_work); } -/* if still more pending work, reset the hangcheck timer: */ -if (fence_after (ring->fctx->last_fence, ring->hangcheck_fence)) -hangcheck_timer_reset (gpu); -/* workaround for missing irq: */ msm_gpu_retire (gpu); }
Signature · 1 line
2.36.1
PATCH 2/2 drm/msm/rd: Fix FIFO-full deadlock
From: Rob Clark <[email protected]>
If the previous thing cat'ing $debugfs/rd left the FIFO full, then subsequent open could deadlock in rd_write() (because open is blocked, not giving a chance for read() to consume any data in the FIFO). Also it is generally a good idea to clear out old data from the FIFO.
--- drivers/gpu/drm/msm/msm_rd.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/msm/msm_rd.c +3 -0
@@ -196,6 +196,9 @@ static int rd_open(struct inode *inode, struct file *file) file->private_data = rd; rd->open = true; +/* Reset fifo to clear any previously unread data: */ + rd->fifo.head = rd->fifo.tail =0 ; +/* the parsing tools need to know gpu-id to know which * register database to load. *
Signature · 1 line
2.36.1
Quoted 53 lines · Rob Clark
From: Rob Clark <[email protected]>
Don't directly restart the hangcheck timer from the timer handler, but instead start it after the
recover_workerreplays remaining jobs.If the kthread is blocked for other reasons, there is no point to immediately restart the timer. Fixes a random symptom of the problem fixed in the next patch.
Signed-off-by Rob Clark <[email protected]>--- drivers/gpu/drm/msm/msm_gpu.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)drivers/gpu/drm/msm/msm_gpu.c +9
-1@@ -328,6 +328,7 @@ find_submit(struct msm_ringbuffer *ring, uint32_t fence) }static void retire_submits (struct msm_gpu *gpu); +static void hangcheck_timer_reset (struct msm_gpu *gpu);static void get_comm_cmdline (struct msm_gem_submit *submit,char **comm,char **cmd) {@@ -420,6 +421,8 @@ static void recover_worker(struct kthread_work *work) }if (msm_gpu_active (gpu)) { +bool restart_hangcheck = false; +/* retire completed submits, plus the one that hung: */ retire_submits (gpu);@@ -436,10 +439,15 @@ static void recover_worker(struct kthread_work *work)unsigned long flags;spin_lock_irqsave (&ring->submit_lock, flags); -list_for_each_entry (submit, &ring->submits, node) +list_for_each_entry (submit, &ring->submits, node) { gpu->funcs->submit (gpu, submit); + restart_hangcheck = true; + }spin_unlock_irqrestore (&ring->submit_lock, flags); } + +if (restart_hangcheck) +hangcheck_timer_reset (gpu); }mutex_unlock (&gpu->lock);
drivers/gpu/drm/msm/msm_gpu.c static void hangcheck_handler(struct timer_list *t) · line 518
Quoted 4 lines
drivers/gpu/drm/msm/msm_gpu.c +0
-1@@ -515,10 +523,6 @@ static void hangcheck_handler(struct timer_list *t)kthread_queue_work (gpu->worker, &gpu->recover_work); } -/* if still more pending work, reset the hangcheck timer: */
In the scenario mentioned here, shouldn't we restart the timer?
-Akhil.
Quoted 7 lines
drivers/gpu/drm/msm/msm_gpu.c +0
-3-if (fence_after (ring->fctx->last_fence, ring->hangcheck_fence)) -hangcheck_timer_reset (gpu); -/* workaround for missing irq: */ msm_gpu_retire (gpu); }
Quoted 53 lines · Akhil P Oommen
Quoted 51 lines · Rob Clark
From: Rob Clark <[email protected]>
Don't directly restart the hangcheck timer from the timer handler, but instead start it after the
recover_workerreplays remaining jobs.If the kthread is blocked for other reasons, there is no point to immediately restart the timer. Fixes a random symptom of the problem fixed in the next patch.
Signed-off-by Rob Clark <[email protected]>--- drivers/gpu/drm/msm/msm_gpu.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)drivers/gpu/drm/msm/msm_gpu.c +9
-1@@ -328,6 +328,7 @@ find_submit(struct msm_ringbuffer *ring, uint32_t fence) }static void retire_submits (struct msm_gpu *gpu); +static void hangcheck_timer_reset (struct msm_gpu *gpu);static void get_comm_cmdline (struct msm_gem_submit *submit,char **comm,char **cmd) {@@ -420,6 +421,8 @@ static void recover_worker(struct kthread_work *work) }if (msm_gpu_active (gpu)) { +bool restart_hangcheck = false; +/* retire completed submits, plus the one that hung: */ retire_submits (gpu);@@ -436,10 +439,15 @@ static void recover_worker(struct kthread_work *work)unsigned long flags;spin_lock_irqsave (&ring->submit_lock, flags); -list_for_each_entry (submit, &ring->submits, node) +list_for_each_entry (submit, &ring->submits, node) { gpu->funcs->submit (gpu, submit); + restart_hangcheck = true; + }spin_unlock_irqrestore (&ring->submit_lock, flags); } + +if (restart_hangcheck) +hangcheck_timer_reset (gpu); }
Quoted 7 lines
drivers/gpu/drm/msm/msm_gpu.c static void hangcheck_handler(struct timer_list *t) · line 518
Quoted 6 lines
drivers/gpu/drm/msm/msm_gpu.c +0
-1mutex_unlock (&gpu->lock);@@ -515,10 +523,6 @@ static void hangcheck_handler(struct timer_list *t)kthread_queue_work (gpu->worker, &gpu->recover_work); } -/* if still more pending work, reset the hangcheck timer: */ In the scenario mentioned here, shouldn't we restart the timer?
yeah, actually the case where we don't want to restart the timer is *only* when we schedule recover_work..
BR,
-R
Quoted 10 lines
-Akhil.
Quoted 7 lines
drivers/gpu/drm/msm/msm_gpu.c +0
-3-if (fence_after (ring->fctx->last_fence, ring->hangcheck_fence)) -hangcheck_timer_reset (gpu); -/* workaround for missing irq: */ msm_gpu_retire (gpu); }
Quoted 58 lines · Rob Clark
Quoted 57 lines · Akhil P Oommen
Quoted 56 lines · Rob Clark
From: Rob Clark <[email protected]>
Don't directly restart the hangcheck timer from the timer handler, but instead start it after the
recover_workerreplays remaining jobs.If the kthread is blocked for other reasons, there is no point to immediately restart the timer. Fixes a random symptom of the problem fixed in the next patch.
Signed-off-by Rob Clark <[email protected]>--- drivers/gpu/drm/msm/msm_gpu.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)drivers/gpu/drm/msm/msm_gpu.c +9
-1@@ -328,6 +328,7 @@ find_submit(struct msm_ringbuffer *ring, uint32_t fence) }static void retire_submits (struct msm_gpu *gpu); +static void hangcheck_timer_reset (struct msm_gpu *gpu);static void get_comm_cmdline (struct msm_gem_submit *submit,char **comm,char **cmd) {@@ -420,6 +421,8 @@ static void recover_worker(struct kthread_work *work) }if (msm_gpu_active (gpu)) { +bool restart_hangcheck = false; +/* retire completed submits, plus the one that hung: */ retire_submits (gpu);@@ -436,10 +439,15 @@ static void recover_worker(struct kthread_work *work)unsigned long flags;spin_lock_irqsave (&ring->submit_lock, flags); -list_for_each_entry (submit, &ring->submits, node) +list_for_each_entry (submit, &ring->submits, node) { gpu->funcs->submit (gpu, submit); + restart_hangcheck = true; + }spin_unlock_irqrestore (&ring->submit_lock, flags); } + +if (restart_hangcheck) +hangcheck_timer_reset (gpu); }mutex_unlock (&gpu->lock);@@ -515,10 +523,6 @@ static void hangcheck_handler(struct timer_list *t)kthread_queue_work (gpu->worker, &gpu->recover_work); }
Quoted 7 lines
Quoted 2 lines
drivers/gpu/drm/msm/msm_gpu.c static void hangcheck_handler(struct timer_list *t) · line 518
Quoted 1 line
drivers/gpu/drm/msm/msm_gpu.c +0
-1-/* if still more pending work, reset the hangcheck timer: */ In the scenario mentioned here, shouldn't we restart the timer?
yeah, actually the case where we don't want to restart the timer is *only* when we schedule
recover_work..BR,
-R
Not sure if your codebase is different but based on msm-next branch, when "if (fence != ring->hangcheck_fence)" is true, we now skip rescheduling the timer. I don't think that is what we want. There should be a hangcheck timer running as long as there is an active submit, unless we have scheduled a recover_work here.
-Akhil.
Quoted 9 lines
Quoted 9 lines
-Akhil.
Quoted 7 lines
drivers/gpu/drm/msm/msm_gpu.c +0
-3-if (fence_after (ring->fctx->last_fence, ring->hangcheck_fence)) -hangcheck_timer_reset (gpu); -/* workaround for missing irq: */ msm_gpu_retire (gpu); }
Quoted 65 lines · Akhil P Oommen
Quoted 63 lines · Rob Clark
Quoted 52 lines · Akhil P Oommen
Quoted 51 lines · Rob Clark
From: Rob Clark <[email protected]>
Don't directly restart the hangcheck timer from the timer handler, but instead start it after the
recover_workerreplays remaining jobs.If the kthread is blocked for other reasons, there is no point to immediately restart the timer. Fixes a random symptom of the problem fixed in the next patch.
Signed-off-by Rob Clark <[email protected]>--- drivers/gpu/drm/msm/msm_gpu.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)drivers/gpu/drm/msm/msm_gpu.c +9
-1@@ -328,6 +328,7 @@ find_submit(struct msm_ringbuffer *ring, uint32_t fence) }static void retire_submits (struct msm_gpu *gpu); +static void hangcheck_timer_reset (struct msm_gpu *gpu);static void get_comm_cmdline (struct msm_gem_submit *submit,char **comm,char **cmd) {@@ -420,6 +421,8 @@ static void recover_worker(struct kthread_work *work) }if (msm_gpu_active (gpu)) { +bool restart_hangcheck = false; +/* retire completed submits, plus the one that hung: */ retire_submits (gpu);@@ -436,10 +439,15 @@ static void recover_worker(struct kthread_work *work)unsigned long flags;spin_lock_irqsave (&ring->submit_lock, flags); -list_for_each_entry (submit, &ring->submits, node) +list_for_each_entry (submit, &ring->submits, node) { gpu->funcs->submit (gpu, submit); + restart_hangcheck = true; + }spin_unlock_irqrestore (&ring->submit_lock, flags); } + +if (restart_hangcheck) +hangcheck_timer_reset (gpu); }Quoted 7 lines
drivers/gpu/drm/msm/msm_gpu.c static void hangcheck_handler(struct timer_list *t) · line 518
Quoted 6 lines
drivers/gpu/drm/msm/msm_gpu.c +0
-1mutex_unlock (&gpu->lock);@@ -515,10 +523,6 @@ static void hangcheck_handler(struct timer_list *t)kthread_queue_work (gpu->worker, &gpu->recover_work); } -/* if still more pending work, reset the hangcheck timer: */ In the scenario mentioned here, shouldn't we restart the timer?
yeah, actually the case where we don't want to restart the timer is *only* when we schedule
recover_work..
Quoted 8 lines
Quoted 2 lines
BR,
-RNot sure if your codebase is different but based on msm-next branch, when "if (fence !=
ring->hangcheck_fence)" is true, we now skip rescheduling the timer. I don't think that is what we want. There should be a hangcheck timer running as long as there is an active submit, unless we have scheduled arecover_workhere.
right, v2 will change that to only skip rescheduling the timer in the recover path
BR,
-R
Quoted 11 lines
-Akhil.
Quoted 9 lines
Quoted 9 lines
-Akhil.
Quoted 7 lines
drivers/gpu/drm/msm/msm_gpu.c +0
-3-if (fence_after (ring->fctx->last_fence, ring->hangcheck_fence)) -hangcheck_timer_reset (gpu); -/* workaround for missing irq: */ msm_gpu_retire (gpu); }