Re: [PATCH] drm/msm/dsi: fix race between cmd transfer and host power off

From: Cédric Bellegarde

Date: Thu Mar 19 2026 - 04:54:05 EST



Le 18/03/2026 à 14:57, Dmitry Baryshkov a écrit :
On Wed, Mar 18, 2026 at 11:56:35AM +0100, Cédric Bellegarde wrote:
The transfer function dsi_host_transfer() guards against the DSI host
being inactive by checking msm_host->power_on. However, power_on is
cleared at the end of msm_dsi_host_power_off(), after clocks have
already been disabled. This creates a window where a concurrent DCS
command (e.g. a brightness update from the backlight driver) can pass
the power_on check, call xfer_prepare()/xfer_restore(), and toggle
link clocks that are already being torn down, leaving
disp_cc_mdss_byte0_clk stuck in the 'on' state.

Checking enabled instead of power_on closes the race by rejecting
transfers as soon as the bridge starts tearing down, before any clocks
are touched.
Thanks, but it is not correct. The transfer callback is documented as
requiring to power up the host if it is not on at the time it is
called. Could you please implement corresponding logic?
Hi,

Thank you for your review.

Looking at the mipi_dsi_host_ops documentation: "Also note that those callbacks can be called no matter the state the host is in. Drivers that need the underlying device to be powered to perform these operations will first need to make sure it's been properly enabled."

I would argue that this sentence places the responsibility on the caller to ensure the host is properly enabled before calling transfer(), not on the transfer() implementation itself to power up the hardware.

In our case, powering up the DSI host from within transfer() is not trivially achievable. These arguments and steps are owned by dsi_mgr_bridge_power_on() and are not available at transfer() time without significant architectural changes that would spread power management logic outside the manager.

BTW, I'm quite new to kernel dev, my logic may be totally wrong. If that is indeed the expected behaviour, would a callback mechanism be acceptable, where the manager registers a power_on callback on the host at bridge init time, allowing transfer() to trigger the full power sequence owned by the manager without duplicating it ?

Signed-off-by: Cédric Bellegarde <cedric.bellegarde@xxxxxxxxxxxx>
---
drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 4d75529c0e85..f66f138cfba0 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1652,7 +1652,7 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
int ret;
- if (!msg || !msm_host->power_on)
+ if (!msg || !msm_host->enabled)
return -EINVAL;
mutex_lock(&msm_host->cmd_mutex);
--
2.53.0

Regards,
--
Cédric Bellegarde