* [PATCH 0/2] drm/bridge: add drm_bridge_clear_and_put()
@ 2026-02-06 14:27 Luca Ceresoli
2026-02-06 14:27 ` [PATCH 1/2] " Luca Ceresoli
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Luca Ceresoli @ 2026-02-06 14:27 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Inki Dae,
Jagan Teki, Marek Szyprowski
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
Luca Ceresoli
This small series introduces drm_bridge_clear_and_put(), to give a easy and
safe way to put a bridge reference and clear the pointer without leaving a
possible use-after-free window.
This is part of the work to support hotplug of DRM bridges. The grand plan
was discussed in [0].
Here's the work breakdown (➜ marks the current series):
1. … add refcounting to DRM bridges struct drm_bridge,
based on devm_drm_bridge_alloc()
A. ✔ add new alloc API and refcounting (v6.16)
B. ✔ convert all bridge drivers to new API (v6.17)
C. ✔ kunit tests (v6.17)
D. ✔ add get/put to drm_bridge_add/remove() + attach/detach()
and warn on old allocation pattern (v6.17)
E. … add get/put on drm_bridge accessors
1. ✔ drm_bridge_chain_get_first_bridge(), add cleanup action (v6.18)
2. ✔ drm_bridge_get_prev_bridge() (v6.18)
3. ✔ drm_bridge_get_next_bridge() (v6.19)
4. ✔ drm_for_each_bridge_in_chain() (v6.19)
5. ✔ drm_bridge_connector_init (v6.19)
6. … protect encoder bridge chain with a mutex
7. … of_drm_find_bridge
a. ✔… add of_drm_get_bridge(), convert basic direct users
(v6.20?, one driver still pending)
b. ✔ convert direct of_drm_get_bridge() users, part 2 (v6.20?)
c. ✔ convert direct of_drm_get_bridge() users, part 3 (v6.20?)
d. … convert direct of_drm_get_bridge() users, part 4
e. convert bridge-only drm_of_find_panel_or_bridge() users
8. drm_of_find_panel_or_bridge, *_of_get_bridge
9. ✔ enforce drm_bridge_add before drm_bridge_attach (v6.19)
F. ✔ debugfs improvements
1. ✔ add top-level 'bridges' file (v6.16)
2. ✔ show refcount and list lingering bridges (v6.19)
2. ➜ handle gracefully atomic updates during bridge removal
A. ✔ Add drm_dev_enter/exit() to protect device resources (v6.20?)
B. … protect private_obj removal from list
C. ➜ Add drm_bridge_clear_and_put()
3. … DSI host-device driver interaction
4. ✔ removing the need for the "always-disconnected" connector
5. DRM bridge hotplug
A. Bridge hotplug management in the DRM core
B. Device tree description
[0] https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-0-9d6f2c9c3058@bootlin.com/#t
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Luca Ceresoli (2):
drm/bridge: add drm_bridge_clear_and_put()
drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge
drivers/gpu/drm/bridge/samsung-dsim.c | 6 ++----
drivers/gpu/drm/drm_bridge.c | 34 ++++++++++++++++++++++++++++++++++
include/drm/drm_bridge.h | 1 +
3 files changed, 37 insertions(+), 4 deletions(-)
---
base-commit: 8991256a0a2699415b5e19bdc8f9d86154543546
change-id: 20260206-drm-bridge-atomic-vs-remove-clear_and_put-a424c752a061
Best regards,
--
Luca Ceresoli <luca.ceresoli@bootlin.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] drm/bridge: add drm_bridge_clear_and_put()
2026-02-06 14:27 [PATCH 0/2] drm/bridge: add drm_bridge_clear_and_put() Luca Ceresoli
@ 2026-02-06 14:27 ` Luca Ceresoli
2026-02-06 14:27 ` [PATCH 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge Luca Ceresoli
2026-02-10 19:41 ` Osama Abdelkader
2 siblings, 0 replies; 5+ messages in thread
From: Luca Ceresoli @ 2026-02-06 14:27 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Inki Dae,
Jagan Teki, Marek Szyprowski
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
Luca Ceresoli
Drivers having a struct drm_bridge pointer pointing to a bridge in many
cases hold that reference until the owning device is removed. In those
cases the reference to the bridge can be put in the .remove callback
(possibly using devm actions) or in the .destroy func (possibly with the
help of struct drm_bridge::next_bridge). At those moments the driver should
not be operating anymore and won't dereference the bridge pointer after it
is put.
However there are cases when drivers need to stop holding a reference to a
bridge even when their device is not being removed. This is the case for
bridge hot-unplug, when a bridge is removed but the previous entity (bridge
or encoder) is staying. In such case the "previous entity" needs to put it
but cannot do it via devm or .destroy, because it is not being removed.
The easy way to dispose of such pointer is:
drm_bridge_put(my_priv->some_bridge);
my_priv->some_bridge = NULL;
However this is risky because there is a time window between the two lines
where the reference is put, and thus the bridge could be deallocated, but
the pointer is still assigned. If other functions of the same driver were
invoked concurrently they might dereference my_priv->some_bridge during
that window, resulting in use-after-free.
A correct solution is to clear the pointer before putting the reference,
but that needs a temporary variable:
struct drm_bridge *temp = my_priv->some_bridge;
my_priv->some_bridge = NULL;
drm_bridge_put(temp);
This solution is however annoying to write, so the incorrect version might
still sneak in.
Add a simple, easy to use function to put a bridge after setting its
pointer to NULL in the correct way.
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
This is a renamed version of drm_bridge_put_and_clear() which was sent as
part of a larger patch [0] but with largely rewritten documentation and a
detailed commit message.
[0] https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-14-9d6f2c9c3058@bootlin.com/
---
drivers/gpu/drm/drm_bridge.c | 34 ++++++++++++++++++++++++++++++++++
include/drm/drm_bridge.h | 1 +
2 files changed, 35 insertions(+)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 3b165a0d1e77..cbe9f17c3690 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -304,6 +304,9 @@ EXPORT_SYMBOL(drm_bridge_get);
*
* This function decrements the bridge's reference count and frees the
* object if the reference count drops to zero.
+ *
+ * See also drm_bridge_clear_and_put() if you also need to set the pointer
+ * to NULL
*/
void drm_bridge_put(struct drm_bridge *bridge)
{
@@ -312,6 +315,37 @@ void drm_bridge_put(struct drm_bridge *bridge)
}
EXPORT_SYMBOL(drm_bridge_put);
+/**
+ * drm_bridge_clear_and_put - Given a bridge pointer, clear the pointer
+ * then put the bridge
+ * @bridge_pp: pointer to pointer to a struct drm_bridge; ``bridge_pp``
+ * must be non-NULL; if ``*bridge_pp`` is NULL this function
+ * does nothing
+ *
+ * Helper to put a DRM bridge, but only after setting its pointer to
+ * NULL. Useful when a struct drm_bridge reference must be dropped without
+ * leaving a use-after-free window where the pointed bridge might have been
+ * freed while still holding a pointer to it.
+ *
+ * For struct ``drm_bridge *some_bridge``, this code::
+ *
+ * drm_bridge_clear_and_put(&some_bridge);
+ *
+ * is equivalent to the more complex::
+ *
+ * struct drm_bridge *temp = some_bridge;
+ * some_bridge = NULL;
+ * drm_bridge_put(temp);
+ */
+void drm_bridge_clear_and_put(struct drm_bridge **bridge_pp)
+{
+ struct drm_bridge *bridge = *bridge_pp;
+
+ *bridge_pp = NULL;
+ drm_bridge_put(bridge);
+}
+EXPORT_SYMBOL(drm_bridge_clear_and_put);
+
/**
* drm_bridge_put_void - wrapper to drm_bridge_put() taking a void pointer
*
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 4f19f7064ee3..66ab89cf48aa 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -1290,6 +1290,7 @@ void drm_bridge_unplug(struct drm_bridge *bridge);
struct drm_bridge *drm_bridge_get(struct drm_bridge *bridge);
void drm_bridge_put(struct drm_bridge *bridge);
+void drm_bridge_clear_and_put(struct drm_bridge **bridge_pp);
/* Cleanup action for use with __free() */
DEFINE_FREE(drm_bridge_put, struct drm_bridge *, if (_T) drm_bridge_put(_T))
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge
2026-02-06 14:27 [PATCH 0/2] drm/bridge: add drm_bridge_clear_and_put() Luca Ceresoli
2026-02-06 14:27 ` [PATCH 1/2] " Luca Ceresoli
@ 2026-02-06 14:27 ` Luca Ceresoli
2026-02-10 19:41 ` Osama Abdelkader
2 siblings, 0 replies; 5+ messages in thread
From: Luca Ceresoli @ 2026-02-06 14:27 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Inki Dae,
Jagan Teki, Marek Szyprowski
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
Luca Ceresoli
drm_bridge_clear_and_put() is simpler to write and it prevents any
potential future use-after-free.
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
drivers/gpu/drm/bridge/samsung-dsim.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
index 1d85e706c74b..568fc0f5b416 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1980,8 +1980,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
return 0;
err_release_next_bridge:
- drm_bridge_put(dsi->bridge.next_bridge);
- dsi->bridge.next_bridge = NULL;
+ drm_bridge_clear_and_put(&dsi->bridge.next_bridge);
return ret;
}
@@ -2002,8 +2001,7 @@ static int samsung_dsim_host_detach(struct mipi_dsi_host *host,
if (pdata->host_ops && pdata->host_ops->detach)
pdata->host_ops->detach(dsi, device);
- drm_bridge_put(dsi->bridge.next_bridge);
- dsi->bridge.next_bridge = NULL;
+ drm_bridge_clear_and_put(&dsi->bridge.next_bridge);
samsung_dsim_unregister_te_irq(dsi);
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge
2026-02-06 14:27 [PATCH 0/2] drm/bridge: add drm_bridge_clear_and_put() Luca Ceresoli
2026-02-06 14:27 ` [PATCH 1/2] " Luca Ceresoli
2026-02-06 14:27 ` [PATCH 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge Luca Ceresoli
@ 2026-02-10 19:41 ` Osama Abdelkader
2026-02-11 7:54 ` Luca Ceresoli
2 siblings, 1 reply; 5+ messages in thread
From: Osama Abdelkader @ 2026-02-10 19:41 UTC (permalink / raw)
To: Luca Ceresoli, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Inki Dae, Jagan Teki, Marek Szyprowski
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel
Hi Luca,
I just reviewed this patch and it looks good to me.
I'm not sure if I'm allowed to add review tag:
Reviewed-by: Osama Abdelkader <osama.abdelkader@gmail.com>
Best regards,
Osama
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge
2026-02-10 19:41 ` Osama Abdelkader
@ 2026-02-11 7:54 ` Luca Ceresoli
0 siblings, 0 replies; 5+ messages in thread
From: Luca Ceresoli @ 2026-02-11 7:54 UTC (permalink / raw)
To: Osama Abdelkader, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Inki Dae, Jagan Teki, Marek Szyprowski
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel
On Tue Feb 10, 2026 at 8:41 PM CET, Osama Abdelkader wrote:
> Hi Luca,
>
> I just reviewed this patch and it looks good to me.
> I'm not sure if I'm allowed to add review tag:
Yes, you are: "Any interested reviewer (who has done the work) can offer
a Reviewed-by tag for a patch."
(https://docs.kernel.org/process/submitting-patches.html#reviewer-s-statement-of-oversight)
> Reviewed-by: Osama Abdelkader <osama.abdelkader@gmail.com>
Thanks!
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-02-11 7:54 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-06 14:27 [PATCH 0/2] drm/bridge: add drm_bridge_clear_and_put() Luca Ceresoli
2026-02-06 14:27 ` [PATCH 1/2] " Luca Ceresoli
2026-02-06 14:27 ` [PATCH 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge Luca Ceresoli
2026-02-10 19:41 ` Osama Abdelkader
2026-02-11 7:54 ` Luca Ceresoli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox