[PATCH 1/6] drm/vc4: Bound the wait for a binner slot in the overflow work

Maíra Canal <[email protected]>
Newsgroups org.freedesktop.lists.dri-devel
Message-ID <[email protected]>
vc4_v3d_get_bin_slot() waits for a render job to retire when every binner
slot is in use, and the wait has no timeout. That suits its caller in
vc4_validate.c, which runs in a user task and already handles -EINTR and
-ERESTARTSYS, but vc4_overflow_mem_work() calls it from a kworker, where
an interruptible wait cannot be broken by a signal.

vc4_reset() cannot get past that. It reaches cancel_work_sync() through
vc4_irq_disable() before it calls vc4_irq_reset(), and
vc4_irq_finish_render_job() is the only place that advances
finished_seqno and wakes the queue. Once the render job being waited on is
itself hung, the work never returns, cancel_work_sync() never completes,
and the reset that would have freed the job never runs.

Pass the timeout in from the caller and give the overflow work a second.
vc4_overflow_mem_work() already handles a failed allocation by leaving the
binner stalled for the hangcheck to reset, and that reset now completes.

Assisted-by: Claude:claude-opus-5
Fixes: 553c942f8b2c ("drm/vc4: Allow using more than 256MB of CMA memory.")
Signed-off-by: Maíra Canal <[email protected]>
---
 drivers/gpu/drm/vc4/vc4_drv.h      | 2 +-
 drivers/gpu/drm/vc4/vc4_irq.c      | 4 +++-
 drivers/gpu/drm/vc4/vc4_v3d.c      | 4 ++--
 drivers/gpu/drm/vc4/vc4_validate.c | 2 +-
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 86e0e7c12901..35b9b574671b 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -1053,7 +1053,7 @@ void vc4_plane_async_set_fb(struct drm_plane *plane,
 /* vc4_v3d.c */
 extern struct platform_driver vc4_v3d_driver;
 extern const struct of_device_id vc4_v3d_dt_match[];
-int vc4_v3d_get_bin_slot(struct vc4_dev *vc4);
+int vc4_v3d_get_bin_slot(struct vc4_dev *vc4, uint64_t timeout_ns);
 int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used);
 void vc4_v3d_bin_bo_put(struct vc4_dev *vc4);
 int vc4_v3d_pm_get(struct vc4_dev *vc4);
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index 90c5194a1c93..95b1a8ad848b 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -57,6 +57,8 @@
 			 V3D_INT_FLDONE | \
 			 V3D_INT_FRDONE)
 
+#define VC4_OVERFLOW_SLOT_TIMEOUT_NS	NSEC_PER_SEC
+
 static void
 vc4_overflow_mem_work(struct work_struct *work)
 {
@@ -74,7 +76,7 @@ vc4_overflow_mem_work(struct work_struct *work)
 
 	bo = vc4->bin_bo;
 
-	bin_bo_slot = vc4_v3d_get_bin_slot(vc4);
+	bin_bo_slot = vc4_v3d_get_bin_slot(vc4, VC4_OVERFLOW_SLOT_TIMEOUT_NS);
 	if (bin_bo_slot < 0) {
 		drm_err(&vc4->base, "Couldn't allocate binner overflow mem\n");
 		goto complete;
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index d2da8d2f8eeb..b943a003bcbc 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -152,7 +152,7 @@ void vc4_v3d_init_hw(struct drm_device *dev)
 	V3D_WRITE(V3D_VPMBASE, 0);
 }
 
-int vc4_v3d_get_bin_slot(struct vc4_dev *vc4)
+int vc4_v3d_get_bin_slot(struct vc4_dev *vc4, uint64_t timeout_ns)
 {
 	struct drm_device *dev = &vc4->base;
 	unsigned long irqflags;
@@ -183,7 +183,7 @@ int vc4_v3d_get_bin_slot(struct vc4_dev *vc4)
 	spin_unlock_irqrestore(&vc4->job_lock, irqflags);
 
 	if (seqno) {
-		int ret = vc4_wait_for_seqno(dev, seqno, ~0ull, true);
+		int ret = vc4_wait_for_seqno(dev, seqno, timeout_ns, true);
 
 		if (ret == 0)
 			goto try_again;
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index 7f2fadfde7a8..a7add99a65a2 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -385,7 +385,7 @@ validate_tile_binning_config(VALIDATE_ARGS)
 		return -EINVAL;
 	}
 
-	bin_slot = vc4_v3d_get_bin_slot(vc4);
+	bin_slot = vc4_v3d_get_bin_slot(vc4, ~0ull);
 	if (bin_slot < 0) {
 		if (bin_slot != -EINTR && bin_slot != -ERESTARTSYS) {
 			drm_err(dev, "Failed to allocate binner memory: %d\n",

-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.