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 <robdclark@chromium.org> Reviewed-by: Akhil P Oommen <akhilpo@codeaurora.org> Link: https://lore.kernel.org/r/20211109181117.591148-5-robdclark@gmail.com Signed-off-by: Rob Clark <robdclark@chromium.org>
This commit is contained in:
parent
c28e2f2b41
commit
5f3aee4ceb
4 changed files with 17 additions and 5 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue