drm/etnaviv: expedited MMU fault handling
authorLucas Stach <l.stach@pengutronix.de>
Wed, 7 Jun 2023 13:02:23 +0000 (15:02 +0200)
committerLucas Stach <l.stach@pengutronix.de>
Mon, 17 Jul 2023 09:32:34 +0000 (11:32 +0200)
The GPU is halted when it hits a MMU exception, so there is no point in
waiting for the job timeout to expire or try to work out if the GPU is
still making progress in the timeout handler, as we know that the GPU
won't make any more progress.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
drivers/gpu/drm/etnaviv/etnaviv_gpu.c
drivers/gpu/drm/etnaviv/etnaviv_gpu.h
drivers/gpu/drm/etnaviv/etnaviv_sched.c

index 53050cf68e1bac775d84d1038e0adc3c713129dd..f54f120906853a01452dc735cc5de711f65b273d 100644 (file)
@@ -1539,6 +1539,8 @@ static irqreturn_t irq_handler(int irq, void *data)
 
                if (intr & VIVS_HI_INTR_ACKNOWLEDGE_MMU_EXCEPTION) {
                        dump_mmu_fault(gpu);
+                       gpu->state = ETNA_GPU_STATE_FAULT;
+                       drm_sched_fault(&gpu->sched);
                        intr &= ~VIVS_HI_INTR_ACKNOWLEDGE_MMU_EXCEPTION;
                }
 
index 85c669dba88e56403df15f22de48e06ad27848f3..197e0037732ec84998aba60b1769a2fc305ea1bf 100644 (file)
@@ -101,6 +101,7 @@ enum etnaviv_gpu_state {
        ETNA_GPU_STATE_RESET,
        ETNA_GPU_STATE_INITIALIZED,
        ETNA_GPU_STATE_RUNNING,
+       ETNA_GPU_STATE_FAULT,
 };
 
 struct etnaviv_gpu {
index 1ae87dfd19c40b092b8ec98318cf58957119d987..345fec6cb1a4c19f24357b0655974049acc1a8ed 100644 (file)
@@ -55,8 +55,9 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job
         */
        dma_addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS);
        change = dma_addr - gpu->hangcheck_dma_addr;
-       if (gpu->completed_fence != gpu->hangcheck_fence ||
-           change < 0 || change > 16) {
+       if (gpu->state == ETNA_GPU_STATE_RUNNING &&
+           (gpu->completed_fence != gpu->hangcheck_fence ||
+            change < 0 || change > 16)) {
                gpu->hangcheck_dma_addr = dma_addr;
                gpu->hangcheck_fence = gpu->completed_fence;
                goto out_no_timeout;