All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Henry Zhang" <henryzhang62@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 2/2] drm/vc4: dsi: Recover from a timed-out transfer
Date: Mon, 12 Oct 2026 19:16:46 +0000	[thread overview]
Message-ID: <sashiko-outbox-168575@kernel.org> (raw)
In-Reply-To: <20261012190249.3167-3-henryzhang62@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] drm/vc4: dsi: premature controller enable during timeout reset causes hardware instability
- [High] drm/vc4: dsi: spurious completion due to IRQ handler TOCTOU race
- [Medium] drm/vc4: missing mutex serialization in DSI host transfer
--

commit b73bc40cfc01c81e251315be152ff0c2c6aa9361
Author: Henry Zhang <henryzhang62@gmail.com>

drm/vc4: dsi: Recover from a timed-out transfer

When a transfer times out, vc4_dsi_host_transfer() disables the command,
resets the FIFOs and returns -ETIMEDOUT. This commit adds a recovery
mechanism that resets the DSI block and its analog front end after a
timeout and restores the configuration so DSI keeps working without a
modeset.

diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index c092a1aaf700a..3783ff3eeac97 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
[ ... ]
@@ -1359,6 +1358,93 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
 	return ret;
 }
 
+/*
+ * Reset the DSI block and its analog front end, then restore the
+ * configuration done in pre_enable. Resetting the FIFOs alone does not
+ * clear the state the block can be left in after a transfer timed out
+ * (e.g. on an LP receive timeout): every following transfer then times
+ * out as well, until the next modeset.
+ */
+static void vc4_dsi_reset_and_restore(struct vc4_dsi *dsi)
+{
+	u32 ctrl = DSI_PORT_READ(CTRL);
+	u32 afec0 = DSI_PORT_READ(PHY_AFEC0);
[ ... ]
+	DSI_PORT_WRITE(DISP0_CTRL, disp0);
+	DSI_PORT_WRITE(TXPKT1C, 0);
+	DSI_PORT_WRITE(CTRL, DSI_CTRL_SOFT_RESET_CFG |
+		       DSI_PORT_BIT(CTRL_RESET_FIFOS));
+	DSI_PORT_WRITE(PHY_AFEC0, afec0 | DSI_PORT_BIT(PHY_AFEC0_RESET));
+	/* AFEC reset hold time */
+	mdelay(1);
+
+	DSI_PORT_WRITE(CTRL, ctrl & ~DSI_CTRL_CAL_BYTE);
+	DSI_PORT_WRITE(HSTX_TO_CNT, hstx_to);
+	DSI_PORT_WRITE(LPRX_TO_CNT, lprx_to);

[Severity: High]
Can writing ctrl & ~DSI_CTRL_CAL_BYTE back to CTRL prematurely un-gate and
enable the controller before the subsequent writes to timing and PHY
configuration registers?

Since ctrl was read while a transfer was in progress, it contains the enable
bit (DSI0_CTRL_CTRL0 or DSI1_CTRL_EN).

Writing it back here enables the hardware block before its timings
(HSTX_TO_CNT, HS_CLT0, PHYC, etc.) are restored, which could cause erratic bus
behavior and unrecoverable hardware states.

> +	DSI_PORT_WRITE(TA_TO_CNT, ta_to);
[ ... ]
+static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
+				     const struct mipi_dsi_msg *msg)
+{
+	struct vc4_dsi *dsi = host_to_dsi(host);
+	u32 disp0_ctrl;
+	ssize_t ret;
+
+	ret = vc4_dsi_transfer(dsi, msg);

[Severity: Medium]
Does this entry point need a mutex to serialize concurrent transfers?

If user-space concurrently triggers DCS commands (e.g., via sysfs backlight
updates and DRM KMS modesets), they can race because vc4_dsi_transfer()
modifies shared variables like dsi->xfer_completion without a lock.

With this patch, a timeout caused by such a race now triggers a full block
reset in vc4_dsi_reset_and_restore(), disrupting any interleaved concurrent
transfer.

+	if (ret != -ETIMEDOUT)
+		return ret;
+
+	/*
+	 * Leave the block usable for the next transfer. The message is not
+	 * resent: it may already have reached the peripheral, and only the
+	 * caller knows whether it is safe to repeat.
+	 */
+	disp0_ctrl = DSI_PORT_READ(DISP0_CTRL);
+	dev_warn(&dsi->pdev->dev,
+		 "transfer timed out (stat 0x%08x), resetting DSI\n",
+		 DSI_PORT_READ(STAT));
+	vc4_dsi_reset_and_restore(dsi);
+	DSI_PORT_WRITE(DISP0_CTRL, disp0_ctrl);
+
+	return ret;
+}

[Severity: High]
Can a timed-out transfer cause a spurious completion of a subsequent transfer?

If vc4_dsi_transfer() times out, wait_for_completion_timeout() returns.
However, if the hardware interrupt had fired and the threaded IRQ handler
(vc4_dsi_irq_handler) was preempted before calling
complete(&dsi->xfer_completion), it could still be pending.

Since there is no synchronization (like synchronize_irq()) in this timeout
recovery path to wait for the IRQ handler to finish, it returns immediately.

The caller might retry the transfer, reinitializing dsi->xfer_completion. The
preempted IRQ thread could then resume, calling complete() and falsely waking up
the new transfer prematurely while the hardware is still busy.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261012190249.3167-1-henryzhang62@gmail.com?part=2

      reply	other threads:[~2026-10-12 19:16 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-12 19:02 [PATCH 0/2] drm/vc4: dsi: Make failed reads visible and recoverable Henry Zhang
2026-10-12 19:02 ` [PATCH 1/2] drm/vc4: dsi: Don't return error reports as read data Henry Zhang
2026-10-12 19:02 ` [PATCH 2/2] drm/vc4: dsi: Recover from a timed-out transfer Henry Zhang
2026-10-12 19:16   ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-168575@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=henryzhang62@gmail.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.