From: Jose Maria Casanova Crespo <[email protected]>

v3d_csd_job_timedout() only treats a change in CSD_CURRENT_CFG4, the
number of batches still to be started, as progress. Once the last batch
has started, CFG4 no longer changes until the dispatch completes, so the
batches still in flight must complete within one timeout period.

Since V3D 7.1 the dispatcher can keep up to MAX_SG_ID + 1 supergroups in
flight. With supergroups of different lengths, the ones still running
after the last batch starts can take longer than that while they keep
completing, and the job is reset although it is making progress.

On V3D 7.x, CSD_EXT_STATUS reports how many supergroup IDs are allocated.
An ID is released when its supergroup completes, and none is allocated
after the last batch has started, so the count only decreases until the
dispatch completes.

Treat a change of that count as progress too, starting from zero IDs when
the job is started. V3D 4.2 has no register that reports supergroup
completion, so it keeps the current behaviour.

Signed-off-by: Jose Maria Casanova Crespo <[email protected]>
Signed-off-by: Maíra Canal <[email protected]>
---
 drivers/gpu/drm/v3d/v3d_drv.h   |  2 +-
 drivers/gpu/drm/v3d/v3d_regs.h  |  5 +++++
 drivers/gpu/drm/v3d/v3d_sched.c | 14 +++++++++++++-
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
index 29fa14be130b..deac9e6a2e42 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.h
+++ b/drivers/gpu/drm/v3d/v3d_drv.h
@@ -426,7 +426,7 @@ struct v3d_tfu_job {
 struct v3d_csd_job {
        struct v3d_job base;
 
-       u32 timedout_batches;
+       u32 timedout_batches, timedout_sg_ids;
 
        struct drm_v3d_submit_csd args;
 };
diff --git a/drivers/gpu/drm/v3d/v3d_regs.h b/drivers/gpu/drm/v3d/v3d_regs.h
index c1870265eaee..8b8199ecb086 100644
--- a/drivers/gpu/drm/v3d/v3d_regs.h
+++ b/drivers/gpu/drm/v3d/v3d_regs.h
@@ -412,6 +412,11 @@
 # define V3D_CSD_STATUS_HAVE_CURRENT_DISPATCH          BIT(1)
 # define V3D_CSD_STATUS_HAVE_QUEUED_DISPATCH           BIT(0)
 
+/* V3D 7.x+ only */
+#define V3D_V7_CSD_EXT_STATUS                           0x00904
+# define V3D_V7_CSD_EXT_STATUS_NUM_ALLOCED_SG_IDS_MASK  V3D_MASK(9, 3)
+# define V3D_V7_CSD_EXT_STATUS_NUM_ALLOCED_SG_IDS_SHIFT 3
+
 #define V3D_CSD_QUEUED_CFG0(ver) ((ver >= 71) ? 0x00930 : 0x00904)
 # define V3D_CSD_QUEUED_CFG0_NUM_WGS_X_MASK            V3D_MASK(31, 16)
 # define V3D_CSD_QUEUED_CFG0_NUM_WGS_X_SHIFT           16
diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c
index 002116efc874..b9e0b7babaf9 100644
--- a/drivers/gpu/drm/v3d/v3d_sched.c
+++ b/drivers/gpu/drm/v3d/v3d_sched.c
@@ -361,6 +361,7 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)
        job->base.irq_fence = dma_fence_get(fence);
 
        job->timedout_batches = job->args.cfg[4];
+       job->timedout_sg_ids = 0;
 
        trace_v3d_submit_csd(dev, to_v3d_fence(fence)->seqno);
 
@@ -776,12 +777,23 @@ v3d_csd_job_timedout(struct drm_sched_job *sched_job)
        struct v3d_csd_job *job = to_csd_job(sched_job);
        struct v3d_dev *v3d = job->base.v3d;
        u32 batches = V3D_CORE_READ(0, V3D_CSD_CURRENT_CFG4(v3d->ver));
+       u32 sg_ids = 0;
+
+       /* Once the last batch has started, CFG4 no longer changes until the
+        * dispatch completes. On V3D 7.x, supergroups that complete in that
+        * window release their ID, so count that as progress too.
+        */
+       if (v3d->ver >= V3D_GEN_71) {
+               sg_ids = V3D_GET_FIELD(V3D_CORE_READ(0, V3D_V7_CSD_EXT_STATUS),
+                                      
V3D_V7_CSD_EXT_STATUS_NUM_ALLOCED_SG_IDS);
+       }
 
        /* If we've made progress, skip reset, add the job to the pending
         * list, and let the timer get rearmed.
         */
-       if (job->timedout_batches != batches) {
+       if (job->timedout_batches != batches || job->timedout_sg_ids != sg_ids) 
{
                job->timedout_batches = batches;
+               job->timedout_sg_ids = sg_ids;
 
                return DRM_GPU_SCHED_STAT_NO_HANG;
        }
-- 
2.56.0

Reply via email to