mbox series

[00/10] drm/connector: add eld_mutex to protect connector->eld

Message ID 20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org
Headers show
Series drm/connector: add eld_mutex to protect connector->eld | expand

Message

Dmitry Baryshkov Nov. 30, 2024, 11:55 p.m. UTC
The connector->eld is accessed by the .get_eld() callback. This access
can collide with the drm_edid_to_eld() updating the data at the same
time. Add drm_connector.eld_mutex to protect the data from concurrenct
access.

The individual drivers were just compile tested. I propose to merge the
drm_connector and bridge drivers through drm-misc, allowing other
maintainers either to ack merging through drm-misc or merging the
drm-misc into their tree and then picking up correcponding patch.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
Dmitry Baryshkov (10):
      drm/connector: add mutex to protect ELD from concurrent access
      drm/bridge: anx7625: use eld_mutex to protect access to connector->eld
      drm/bridge: ite-it66121: use eld_mutex to protect access to connector->eld
      drm/amd/display: use eld_mutex to protect access to connector->eld
      drm/exynos: hdmi: use eld_mutex to protect access to connector->eld
      drm/i915/audio: use eld_mutex to protect access to connector->eld
      drm/msm/dp: use eld_mutex to protect access to connector->eld
      drm/radeon: use eld_mutex to protect access to connector->eld
      drm/sti: hdmi: use eld_mutex to protect access to connector->eld
      drm/vc4: hdmi: use eld_mutex to protect access to connector->eld

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
 drivers/gpu/drm/bridge/analogix/anx7625.c         | 2 ++
 drivers/gpu/drm/bridge/ite-it66121.c              | 2 ++
 drivers/gpu/drm/drm_connector.c                   | 1 +
 drivers/gpu/drm/drm_edid.c                        | 4 ++++
 drivers/gpu/drm/exynos/exynos_hdmi.c              | 2 ++
 drivers/gpu/drm/i915/display/intel_audio.c        | 3 +++
 drivers/gpu/drm/msm/dp/dp_audio.c                 | 2 ++
 drivers/gpu/drm/radeon/radeon_audio.c             | 2 ++
 drivers/gpu/drm/sti/sti_hdmi.c                    | 2 ++
 drivers/gpu/drm/vc4/vc4_hdmi.c                    | 4 ++--
 include/drm/drm_connector.h                       | 5 ++++-
 12 files changed, 28 insertions(+), 3 deletions(-)
---
base-commit: 44cff6c5b0b17a78bc0b30372bcd816cf6dd282a
change-id: 20241201-drm-connector-eld-mutex-8a39a35e9a38

Best regards,

Comments

Maxime Ripard Dec. 2, 2024, 10:19 a.m. UTC | #1
On Sun, 1 Dec 2024 01:55:17 +0200, Dmitry Baryshkov wrote:
> The connector->eld is accessed by the .get_eld() callback. This access
> can collide with the drm_edid_to_eld() updating the data at the same
> time. Add drm_connector.eld_mutex to protect the data from concurrenct
> access.
> 
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard@kernel.org>

Thanks!
Maxime
Jani Nikula Dec. 2, 2024, 10:23 a.m. UTC | #2
On Sun, 01 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
> The connector->eld is accessed by the .get_eld() callback. This access
> can collide with the drm_edid_to_eld() updating the data at the same
> time. Add drm_connector.eld_mutex to protect the data from concurrenct
> access. Individual drivers are not updated (to reduce possible issues
> while applying the patch), maintainers are to find a best suitable way
> to lock that mutex while accessing the ELD data.

Missed clear_eld().

BR,
Jani.

>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/gpu/drm/drm_connector.c | 1 +
>  drivers/gpu/drm/drm_edid.c      | 4 ++++
>  include/drm/drm_connector.h     | 5 ++++-
>  3 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index fc35f47e2849ed6786d6223ac9c69e1c359fc648..bbdaaf7022b62d84594a29f1b60144920903a99a 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -277,6 +277,7 @@ static int __drm_connector_init(struct drm_device *dev,
>  	INIT_LIST_HEAD(&connector->probed_modes);
>  	INIT_LIST_HEAD(&connector->modes);
>  	mutex_init(&connector->mutex);
> +	mutex_init(&connector->eld_mutex);
>  	mutex_init(&connector->edid_override_mutex);
>  	mutex_init(&connector->hdmi.infoframes.lock);
>  	connector->edid_blob_ptr = NULL;
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 855beafb76ffbecf5c08d58e2f54bfb76f30b930..f0ca77bd42fd518d505d0db78557e0c8d83efb29 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -5657,6 +5657,8 @@ static void drm_edid_to_eld(struct drm_connector *connector,
>  	if (!drm_edid)
>  		return;
>  
> +	mutex_lock(&connector->eld_mutex);
> +
>  	mnl = get_monitor_name(drm_edid, &eld[DRM_ELD_MONITOR_NAME_STRING]);
>  	drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD monitor %s\n",
>  		    connector->base.id, connector->name,
> @@ -5717,6 +5719,8 @@ static void drm_edid_to_eld(struct drm_connector *connector,
>  	drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD size %d, SAD count %d\n",
>  		    connector->base.id, connector->name,
>  		    drm_eld_size(eld), total_sad_count);
> +
> +	mutex_unlock(&connector->eld_mutex);
>  }
>  
>  static int _drm_edid_to_sad(const struct drm_edid *drm_edid,
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index e3fa43291f449d70f3b92a00985336c4f2237bc6..1e2b25e204cb523d61d30f5409faa059bf2b86eb 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -2001,8 +2001,11 @@ struct drm_connector {
>  	struct drm_encoder *encoder;
>  
>  #define MAX_ELD_BYTES	128
> -	/** @eld: EDID-like data, if present */
> +	/** @eld: EDID-like data, if present, protected by @eld_mutex */
>  	uint8_t eld[MAX_ELD_BYTES];
> +	/** @eld_mutex: protection for concurrenct access to @eld */
> +	struct mutex eld_mutex;
> +
>  	/** @latency_present: AV delay info from ELD, if found */
>  	bool latency_present[2];
>  	/**
Dmitry Baryshkov Dec. 2, 2024, 11:03 a.m. UTC | #3
On Mon, Dec 02, 2024 at 10:19:41AM +0000, Maxime Ripard wrote:
> On Sun, 1 Dec 2024 01:55:17 +0200, Dmitry Baryshkov wrote:
> > The connector->eld is accessed by the .get_eld() callback. This access
> > can collide with the drm_edid_to_eld() updating the data at the same
> > time. Add drm_connector.eld_mutex to protect the data from concurrenct
> > access.
> > 
> > 
> > [ ... ]
> 
> Reviewed-by: Maxime Ripard <mripard@kernel.org>

Thanks!

I'm going to post v2 to fix Jani's comment, but what should be the merge
strategy? Merge patches 1-3, 5, 9-10 through drm-misc and the rest (AMD,
i915, MSM, radeon) through the driver trees?
Maxime Ripard Dec. 2, 2024, noon UTC | #4
On Mon, Dec 02, 2024 at 01:03:07PM +0200, Dmitry Baryshkov wrote:
> On Mon, Dec 02, 2024 at 10:19:41AM +0000, Maxime Ripard wrote:
> > On Sun, 1 Dec 2024 01:55:17 +0200, Dmitry Baryshkov wrote:
> > > The connector->eld is accessed by the .get_eld() callback. This access
> > > can collide with the drm_edid_to_eld() updating the data at the same
> > > time. Add drm_connector.eld_mutex to protect the data from concurrenct
> > > access.
> > > 
> > > 
> > > [ ... ]
> > 
> > Reviewed-by: Maxime Ripard <mripard@kernel.org>
> 
> Thanks!
> 
> I'm going to post v2 to fix Jani's comment, but what should be the merge
> strategy? Merge patches 1-3, 5, 9-10 through drm-misc and the rest (AMD,
> i915, MSM, radeon) through the driver trees?

The easiest is probably to merge everything through drm-misc if everyone agrees.

Maxime
Raphaël Gallais-Pou Dec. 2, 2024, 3:03 p.m. UTC | #5
Le 01/12/2024 à 00:55, Dmitry Baryshkov a écrit :
> Reading access to connector->eld can happen at the same time the
> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
> order to protect connector->eld from concurrent access.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Hi Dmitry,

Acked-by: Raphael Gallais-Pou <rgallaispou@gmail.com>

Thanks,
Raphaël
> ---
>   drivers/gpu/drm/sti/sti_hdmi.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
> index 847470f747c0efad61c2ebdc3fb3746a7a13a863..3c8f3532c79723e7b1a720c855c90e40584cc6ca 100644
> --- a/drivers/gpu/drm/sti/sti_hdmi.c
> +++ b/drivers/gpu/drm/sti/sti_hdmi.c
> @@ -1225,7 +1225,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size
>   	struct drm_connector *connector = hdmi->drm_connector;
>   
>   	DRM_DEBUG_DRIVER("\n");
> +	mutex_lock(&connector->eld_mutex);
>   	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
> +	mutex_unlock(&connector->eld_mutex);
>   
>   	return 0;
>   }
>