From 5f3aee4ceb5b8607e9a4b752c2547667200e19e2 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 9 Nov 2021 10:11:04 -0800 Subject: [PATCH] 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: Rob Clark Reviewed-by: Akhil P Oommen Link: https://lore.kernel.org/r/20211109181117.591148-5-robdclark@gmail.com Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 2 +- drivers/gpu/drm/msm/msm_fence.h | 12 ++++++++++++ drivers/gpu/drm/msm/msm_gpu.c | 6 +++--- drivers/gpu/drm/msm/msm_gpu.h | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b097bc3..91cc451 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -967,7 +967,7 @@ static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, struct dma_fence *fence; 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", fence_id, queue->last_fence); return -EINVAL; diff --git a/drivers/gpu/drm/msm/msm_fence.h b/drivers/gpu/drm/msm/msm_fence.h index 4783db5..17ee382 100644 --- a/drivers/gpu/drm/msm/msm_fence.h +++ b/drivers/gpu/drm/msm/msm_fence.h @@ -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); +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 diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 13de124..0f78c26 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -172,7 +172,7 @@ static void update_fences(struct msm_gpu *gpu, struct msm_ringbuffer *ring, spin_lock_irqsave(&ring->submit_lock, flags); list_for_each_entry(submit, &ring->submits, node) { - if (submit->seqno > fence) + if (fence_after(submit->seqno, fence)) break; msm_update_fence(submit->ring->fctx, @@ -509,7 +509,7 @@ static void hangcheck_handler(struct timer_list *t) if (fence != ring->hangcheck_fence) { /* some progress has been made.. ya! */ ring->hangcheck_fence = fence; - } else if (fence < ring->seqno) { + } else if (fence_before(fence, ring->seqno)) { /* no progress and not done.. hung! */ ring->hangcheck_fence = fence; 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) } /* 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); /* workaround for missing irq: */ diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 0078a92..37b3ecb 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -262,7 +262,7 @@ static inline bool msm_gpu_active(struct msm_gpu *gpu) for (i = 0; i < gpu->nr_rings; i++) { struct msm_ringbuffer *ring = gpu->rb[i]; - if (ring->seqno > ring->memptrs->fence) + if (fence_after(ring->seqno, ring->memptrs->fence)) return true; } -- 2.7.4