drm/v3d: Delay the scheduler timeout if we're still making progress.
authorEric Anholt <eric@anholt.net>
Tue, 3 Jul 2018 17:05:12 +0000 (10:05 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 5 Jul 2018 18:42:49 +0000 (11:42 -0700)
GTF-GLES2.gtf.GL.acos.acos_float_vert_xvary submits jobs that take 4
seconds at maximum resolution, but we still want to reset quickly if a
job is really hung.  Sample the CL's current address and the return
address (since we call into tile lists repeatedly) and if either has
changed then assume we've made progress.

Signed-off-by: Eric Anholt <eric@anholt.net>
Cc: Lucas Stach <l.stach@pengutronix.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20180703170515.6298-1-eric@anholt.net
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Daniel Vetter <daniel@ffwll.ch>
drivers/gpu/drm/v3d/v3d_drv.h
drivers/gpu/drm/v3d/v3d_regs.h
drivers/gpu/drm/v3d/v3d_sched.c

index 282763c9c7f6b29bded7f9ee97c6dc05239afa39..e6fed696ad869e2d700a94c2e6f4a10d36bf7529 100644 (file)
@@ -184,6 +184,8 @@ struct v3d_job {
 
        /* GPU virtual addresses of the start/end of the CL job. */
        u32 start, end;
+
+       u32 timedout_ctca, timedout_ctra;
 };
 
 struct v3d_exec_info {
index fc13282dfc2f0b75dc3ea167180950b63f7c8a76..854046565989e12c5b2e822f82b8fae40c01e5b0 100644 (file)
 #define V3D_CLE_CTNCA(n) (V3D_CLE_CT0CA + 4 * n)
 #define V3D_CLE_CT0RA                                  0x00118
 #define V3D_CLE_CT1RA                                  0x0011c
+#define V3D_CLE_CTNRA(n) (V3D_CLE_CT0RA + 4 * n)
 #define V3D_CLE_CT0LC                                  0x00120
 #define V3D_CLE_CT1LC                                  0x00124
 #define V3D_CLE_CT0PC                                  0x00128
index 808bc901f567f2aaa81acbaa3e64e70640c44317..00667c733dca05ffcb02baaff7133bf16917420d 100644 (file)
@@ -153,7 +153,25 @@ v3d_job_timedout(struct drm_sched_job *sched_job)
        struct v3d_job *job = to_v3d_job(sched_job);
        struct v3d_exec_info *exec = job->exec;
        struct v3d_dev *v3d = exec->v3d;
+       enum v3d_queue job_q = job == &exec->bin ? V3D_BIN : V3D_RENDER;
        enum v3d_queue q;
+       u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(job_q));
+       u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(job_q));
+
+       /* If the current address or return address have changed, then
+        * the GPU has probably made progress and we should delay the
+        * reset.  This could fail if the GPU got in an infinite loop
+        * in the CL, but that is pretty unlikely outside of an i-g-t
+        * testcase.
+        */
+       if (job->timedout_ctca != ctca || job->timedout_ctra != ctra) {
+               job->timedout_ctca = ctca;
+               job->timedout_ctra = ctra;
+
+               schedule_delayed_work(&job->base.work_tdr,
+                                     job->base.sched->timeout);
+               return;
+       }
 
        mutex_lock(&v3d->reset_lock);