]> git.ipfire.org Git - thirdparty/linux.git/commit
drm/bridge: add drm_bridge_clear_and_put()
authorLuca Ceresoli <luca.ceresoli@bootlin.com>
Tue, 10 Mar 2026 12:13:23 +0000 (13:13 +0100)
committerLuca Ceresoli <luca.ceresoli@bootlin.com>
Fri, 20 Mar 2026 10:02:12 +0000 (11:02 +0100)
commit8f3c83720555ffa96799896f2a0bb985a03a89f4
tree436c7ef03b86875150121eee5d085495646c69d4
parent5f1d250a8fc4a4975b692e30229ad93a20c3778a
drm/bridge: add drm_bridge_clear_and_put()

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.

Acked-by: Maxime Ripard <mripard@kernel.org>
Link: https://patch.msgid.link/20260310-drm-bridge-atomic-vs-remove-clear_and_put-v2-1-51fe222f3cf0@bootlin.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
drivers/gpu/drm/drm_bridge.c
include/drm/drm_bridge.h