[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251003-drm-bridge-alloc-encoder-chain-mutex-v2-6-78bf61580a06@bootlin.com>
Date: Fri, 03 Oct 2025 12:39:28 +0200
From: Luca Ceresoli <luca.ceresoli@...tlin.com>
To: Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
Maxime Ripard <mripard@...nel.org>, Thomas Zimmermann <tzimmermann@...e.de>,
David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>,
Andrzej Hajda <andrzej.hajda@...el.com>,
Neil Armstrong <neil.armstrong@...aro.org>, Robert Foss <rfoss@...nel.org>,
Laurent Pinchart <Laurent.pinchart@...asonboard.com>,
Jonas Karlman <jonas@...boo.se>, Jernej Skrabec <jernej.skrabec@...il.com>
Cc: Hui Pu <Hui.Pu@...ealthcare.com>,
Thomas Petazzoni <thomas.petazzoni@...tlin.com>,
dri-devel@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
Luca Ceresoli <luca.ceresoli@...tlin.com>
Subject: [PATCH v2 6/7] drm/bridge: prevent encoder chain changes while
iterating with list_for_each_entry_reverse()
These loops in drm_bridge.c iterate over the encoder chain using
list_for_each_entry_reverse(), which does not prevent changes to the bridge
chain while iterating over it.
Take the encoder chain mutex while iterating to avoid chain changes while
iterating.
All the "simple" loops are converted. drm_atomic_bridge_chain_pre_enable()
and drm_atomic_bridge_chain_post_disable() are handled by a separate
commit.
Signed-off-by: Luca Ceresoli <luca.ceresoli@...tlin.com>
---
drivers/gpu/drm/drm_bridge.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index be38dd7eefed0539795f721738e1f1df324d9a6f..2a55ac5697e0b4faa21f01728bbe287a95cd99a6 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -701,6 +701,7 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
return;
encoder = bridge->encoder;
+ drm_encoder_chain_lock(encoder);
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
if (iter->funcs->atomic_disable) {
iter->funcs->atomic_disable(iter, state);
@@ -711,6 +712,7 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
if (iter == bridge)
break;
}
+ drm_encoder_chain_unlock(encoder);
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);
@@ -1215,6 +1217,7 @@ int drm_atomic_bridge_chain_check(struct drm_bridge *bridge,
return ret;
encoder = bridge->encoder;
+ drm_encoder_chain_lock(encoder);
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
int ret;
@@ -1229,12 +1232,15 @@ int drm_atomic_bridge_chain_check(struct drm_bridge *bridge,
crtc_state->state);
ret = drm_atomic_bridge_check(iter, crtc_state, conn_state);
- if (ret)
+ if (ret) {
+ drm_encoder_chain_unlock(encoder);
return ret;
+ }
if (iter == bridge)
break;
}
+ drm_encoder_chain_unlock(encoder);
return 0;
}
--
2.51.0
Powered by blists - more mailing lists