All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luca Ceresoli <luca.ceresoli@bootlin.com>
To: Maxime Ripard <mripard@kernel.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Andrzej Hajda <andrzej.hajda@intel.com>,
	Neil Armstrong <neil.armstrong@linaro.org>,
	Robert Foss <rfoss@kernel.org>,
	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
	Jonas Karlman <jonas@kwiboo.se>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	Hui Pu <Hui.Pu@gehealthcare.com>,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/7] drm/encoder: add mutex to protect the bridge chain
Date: Mon, 29 Sep 2025 16:45:26 +0200	[thread overview]
Message-ID: <20250929164526.08aa8118@booty> (raw)
In-Reply-To: <20250929-strange-earthworm-of-research-d2bbab@houat>

Hi Maxime,

On Mon, 29 Sep 2025 14:43:46 +0200
Maxime Ripard <mripard@kernel.org> wrote:

> On Fri, Sep 26, 2025 at 05:59:42PM +0200, Luca Ceresoli wrote:
> > The per-encoder bridge chain is currently assumed to be static once it is
> > fully initialized. Work is in progress to add hot-pluggable bridges,
> > breaking that assumption.
> > 
> > With bridge removal, the encoder chain can change without notice, removing
> > tail bridges. This can be problematic while iterating over the chain.
> > 
> > Add a mutex to be taken whenever looping or changing the encoder chain.
> > 
> > Also add two APIs to lock/unlock the mutex without the need to manipulate
> > internal struct drm_encoder fields.
> > 
> > Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> > ---
> >  drivers/gpu/drm/drm_encoder.c |  2 ++
> >  include/drm/drm_encoder.h     | 18 ++++++++++++++++++
> >  2 files changed, 20 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
> > index 8f2bc6a28482229fd0b030a1958f87753ad7885f..3261f142baea30c516499d23dbf8d0acf5952cd6 100644
> > --- a/drivers/gpu/drm/drm_encoder.c
> > +++ b/drivers/gpu/drm/drm_encoder.c
> > @@ -129,6 +129,7 @@ static int __drm_encoder_init(struct drm_device *dev,
> >  	}
> >  
> >  	INIT_LIST_HEAD(&encoder->bridge_chain);
> > +	mutex_init(&encoder->bridge_chain_mutex);
> >  	list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
> >  	encoder->index = dev->mode_config.num_encoder++;
> >  
> > @@ -202,6 +203,7 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
> >  	kfree(encoder->name);
> >  	list_del(&encoder->head);
> >  	dev->mode_config.num_encoder--;
> > +	mutex_destroy(&encoder->bridge_chain_mutex);
> >  
> >  	memset(encoder, 0, sizeof(*encoder));
> >  }
> > diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
> > index 977a9381c8ba943b4d3e021635ea14856df8a17d..6c962de640a345bfbb18308c83076628547c9ab9 100644
> > --- a/include/drm/drm_encoder.h
> > +++ b/include/drm/drm_encoder.h
> > @@ -25,6 +25,7 @@
> >  
> >  #include <linux/list.h>
> >  #include <linux/ctype.h>
> > +#include <linux/mutex.h>
> >  #include <drm/drm_crtc.h>
> >  #include <drm/drm_mode.h>
> >  #include <drm/drm_mode_object.h>
> > @@ -189,6 +190,9 @@ struct drm_encoder {
> >  	 */
> >  	struct list_head bridge_chain;
> >  
> > +	/** @bridge_chain_mutex: protect bridge_chain from changes while iterating */
> > +	struct mutex bridge_chain_mutex;
> > +
> >  	const struct drm_encoder_funcs *funcs;
> >  	const struct drm_encoder_helper_funcs *helper_private;
> >  
> > @@ -319,6 +323,20 @@ static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
> >  	return mo ? obj_to_encoder(mo) : NULL;
> >  }
> >  
> > +static inline struct drm_encoder *drm_encoder_chain_lock(struct drm_encoder *encoder)
> > +{
> > +	if (!WARN_ON_ONCE(!encoder))
> > +		mutex_lock(&encoder->bridge_chain_mutex);
> > +
> > +	return encoder;
> > +}
> > +
> > +static inline void drm_encoder_chain_unlock(struct drm_encoder *encoder)
> > +{
> > +	if (!WARN_ON_ONCE(!encoder))
> > +		mutex_unlock(&encoder->bridge_chain_mutex);
> > +}
> > +  
> 
> Please provide documentation for these two functions.

Ah, sure, here is a draft:

/**
 * drm_encoder_chain_lock - lock the encoder bridge chain
 * @encoder: encoder whose bridge chain must be locked
 *
 * Locks the mutex protecting the bridge chain from concurrent access.
 * To be called by code modifying ot iterating over the bridge chain to
 * prevent the list from changing while iterating over it.
 * Call drm_encoder_chain_unlock() to unlock the mutex.
 *
 * Returns:
 * Pointer to @encoder. Useful to lock the chain and then operate on the
 * in the same statement, e.g.
 * list_first_entry(&drm_encoder_chain_lock(encoder)->bridge_chain)
 */
static inline struct drm_encoder *drm_encoder_chain_lock(struct drm_encoder *encoder)
{
	if (!WARN_ON_ONCE(!encoder))
		mutex_lock(&encoder->bridge_chain_mutex);

	return encoder;
}

/**
 * drm_encoder_chain_unlock - unlock the encoder bridge chain
 * @encoder: encoder whose bridge chain must be unlocked
 *
 * Unlocks the mutex protecting the bridge chain from concurrent access,
 * matching drm_encoder_chain_lock().
 */
static inline void drm_encoder_chain_unlock(struct drm_encoder *encoder)
{
	if (!WARN_ON_ONCE(!encoder))
		mutex_unlock(&encoder->bridge_chain_mutex);
}

> In particular, why
> do we need to return the encoder pointer?

It allows to lock the encoder chain and then dereference the pointer,
similar to what drm_bridge_get() does. of_node_get(), which I used as a
model for these functions, does the same.

This one in particular is used in patch 4 to write the new scoped
macros. Locking the encoder chain and then dereferencing the encoder
would be very awkward in a macro if drm_encoder_chain_lock() didn't
return the encoder.

Luca
-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

  reply	other threads:[~2025-09-29 14:45 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-26 15:59 [PATCH 0/7] drm/bridge: protect encoder bridge chain with a mutex Luca Ceresoli
2025-09-26 15:59 ` [PATCH 1/7] drm/encoder: add mutex to protect the bridge chain Luca Ceresoli
2025-09-29 12:43   ` Maxime Ripard
2025-09-29 14:45     ` Luca Ceresoli [this message]
2025-09-26 15:59 ` [PATCH 2/7] drm/encoder: drm_encoder_cleanup: take chain mutex while tearing down Luca Ceresoli
2025-09-29 12:45   ` Maxime Ripard
2025-09-29 14:31     ` Luca Ceresoli
2025-10-03 10:37       ` Luca Ceresoli
2025-09-26 15:59 ` [PATCH 3/7] drm/bridge: lock the encoder bridge chain mutex during insertion Luca Ceresoli
2025-09-29 12:46   ` Maxime Ripard
2025-09-29 14:53     ` Luca Ceresoli
2025-09-26 15:59 ` [PATCH 4/7] drm/bridge: lock the encoder chain in scoped for_each loops Luca Ceresoli
2025-09-30  6:16   ` kernel test robot
2025-10-02 15:33     ` Luca Ceresoli
2025-09-26 15:59 ` [PATCH 5/7] drm/bridge: prevent encoder chain changes while iterating with list_for_each_entry_from() Luca Ceresoli
2025-09-26 15:59 ` [PATCH 6/7] drm/bridge: prevent encoder chain changes while iterating with list_for_each_entry_reverse() Luca Ceresoli
2025-09-26 15:59 ` [PATCH 7/7] drm/bridge: prevent encoder chain changes while iterating in drm_atomic_bridge_chain_post_disable/pre_enable() Luca Ceresoli

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=20250929164526.08aa8118@booty \
    --to=luca.ceresoli@bootlin.com \
    --cc=Hui.Pu@gehealthcare.com \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=airlied@gmail.com \
    --cc=andrzej.hajda@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jernej.skrabec@gmail.com \
    --cc=jonas@kwiboo.se \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=neil.armstrong@linaro.org \
    --cc=rfoss@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=tzimmermann@suse.de \
    /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.