[PATCH AUTOSEL 6.6 03/17] drm/connector: add mutex to protect ELD from concurrent access
Sasha Levin
sashal at kernel.org
Sun Jan 26 14:55:58 UTC 2025
From: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
[ Upstream commit df7c8e3dde37a9d81c0613285b43600f3cc70f34 ]
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.
Reviewed-by: Maxime Ripard <mripard at kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20241206-drm-connector-eld-mutex-v2-1-c9bce1ee8bea@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
drivers/gpu/drm/drm_connector.c | 1 +
drivers/gpu/drm/drm_edid.c | 6 ++++++
include/drm/drm_connector.h | 5 ++++-
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 309aad5f0c808..35bed66214474 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);
connector->edid_blob_ptr = NULL;
connector->epoch_counter = 0;
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index ee3fab115c4b5..ad872c61aac0e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5499,7 +5499,9 @@ EXPORT_SYMBOL(drm_edid_get_monitor_name);
static void clear_eld(struct drm_connector *connector)
{
+ mutex_lock(&connector->eld_mutex);
memset(connector->eld, 0, sizeof(connector->eld));
+ mutex_unlock(&connector->eld_mutex);
connector->latency_present[0] = false;
connector->latency_present[1] = false;
@@ -5530,6 +5532,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,
@@ -5590,6 +5594,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 d300fde6c1a47..b2e9dc02fa349 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1764,8 +1764,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];
/**
--
2.39.5
More information about the dri-devel
mailing list