Commit 5f3aee4c authored by Rob Clark's avatar Rob Clark

drm/msm: Handle fence rollover

Add some helpers for fence comparision, which handle rollover properly,
and stop open coding fence seqno comparisions.
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
Reviewed-by: default avatarAkhil P Oommen <akhilpo@codeaurora.org>
Link: https://lore.kernel.org/r/20211109181117.591148-5-robdclark@gmail.comSigned-off-by: default avatarRob Clark <robdclark@chromium.org>
parent c28e2f2b
...@@ -967,7 +967,7 @@ static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, ...@@ -967,7 +967,7 @@ static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id,
struct dma_fence *fence; struct dma_fence *fence;
int ret; int ret;
if (fence_id > queue->last_fence) { if (fence_after(fence_id, queue->last_fence)) {
DRM_ERROR_RATELIMITED("waiting on invalid fence: %u (of %u)\n", DRM_ERROR_RATELIMITED("waiting on invalid fence: %u (of %u)\n",
fence_id, queue->last_fence); fence_id, queue->last_fence);
return -EINVAL; return -EINVAL;
......
...@@ -60,4 +60,16 @@ void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence); ...@@ -60,4 +60,16 @@ void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence);
struct dma_fence * msm_fence_alloc(struct msm_fence_context *fctx); struct dma_fence * msm_fence_alloc(struct msm_fence_context *fctx);
static inline bool
fence_before(uint32_t a, uint32_t b)
{
return (int32_t)(a - b) < 0;
}
static inline bool
fence_after(uint32_t a, uint32_t b)
{
return (int32_t)(a - b) > 0;
}
#endif #endif
...@@ -172,7 +172,7 @@ static void update_fences(struct msm_gpu *gpu, struct msm_ringbuffer *ring, ...@@ -172,7 +172,7 @@ static void update_fences(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
spin_lock_irqsave(&ring->submit_lock, flags); spin_lock_irqsave(&ring->submit_lock, flags);
list_for_each_entry(submit, &ring->submits, node) { list_for_each_entry(submit, &ring->submits, node) {
if (submit->seqno > fence) if (fence_after(submit->seqno, fence))
break; break;
msm_update_fence(submit->ring->fctx, msm_update_fence(submit->ring->fctx,
...@@ -509,7 +509,7 @@ static void hangcheck_handler(struct timer_list *t) ...@@ -509,7 +509,7 @@ static void hangcheck_handler(struct timer_list *t)
if (fence != ring->hangcheck_fence) { if (fence != ring->hangcheck_fence) {
/* some progress has been made.. ya! */ /* some progress has been made.. ya! */
ring->hangcheck_fence = fence; ring->hangcheck_fence = fence;
} else if (fence < ring->seqno) { } else if (fence_before(fence, ring->seqno)) {
/* no progress and not done.. hung! */ /* no progress and not done.. hung! */
ring->hangcheck_fence = fence; ring->hangcheck_fence = fence;
DRM_DEV_ERROR(dev->dev, "%s: hangcheck detected gpu lockup rb %d!\n", DRM_DEV_ERROR(dev->dev, "%s: hangcheck detected gpu lockup rb %d!\n",
...@@ -523,7 +523,7 @@ static void hangcheck_handler(struct timer_list *t) ...@@ -523,7 +523,7 @@ static void hangcheck_handler(struct timer_list *t)
} }
/* if still more pending work, reset the hangcheck timer: */ /* if still more pending work, reset the hangcheck timer: */
if (ring->seqno > ring->hangcheck_fence) if (fence_after(ring->seqno, ring->hangcheck_fence))
hangcheck_timer_reset(gpu); hangcheck_timer_reset(gpu);
/* workaround for missing irq: */ /* workaround for missing irq: */
......
...@@ -262,7 +262,7 @@ static inline bool msm_gpu_active(struct msm_gpu *gpu) ...@@ -262,7 +262,7 @@ static inline bool msm_gpu_active(struct msm_gpu *gpu)
for (i = 0; i < gpu->nr_rings; i++) { for (i = 0; i < gpu->nr_rings; i++) {
struct msm_ringbuffer *ring = gpu->rb[i]; struct msm_ringbuffer *ring = gpu->rb[i];
if (ring->seqno > ring->memptrs->fence) if (fence_after(ring->seqno, ring->memptrs->fence))
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment