Create a new global blob_lock mutex, which protects the blob property
list from insertion and/or deletion.

Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 drivers/gpu/drm/drm_crtc.c | 18 +++++++++++++++---
 include/drm/drm_crtc.h     |  3 +++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index ed9341d..9947078 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -4214,25 +4214,34 @@ drm_property_create_blob(struct drm_device *dev, size_t 
length,
        if (!blob)
                return NULL;

+       blob->length = length;
+
+       memcpy(blob->data, data, length);
+
+       mutex_lock(&dev->mode_config.blob_lock);
+
        ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
        if (ret) {
                kfree(blob);
+               mutex_unlock(&dev->mode_config.blob_lock);
                return NULL;
        }

-       blob->length = length;
+       list_add_tail(&blob->head, &dev->mode_config.property_blob_list);

-       memcpy(blob->data, data, length);
+       mutex_unlock(&dev->mode_config.blob_lock);

-       list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
        return blob;
 }

 static void drm_property_destroy_blob(struct drm_device *dev,
                               struct drm_property_blob *blob)
 {
+       mutex_lock(&dev->mode_config.blob_lock);
        drm_mode_object_put(dev, &blob->base);
        list_del(&blob->head);
+       mutex_unlock(&dev->mode_config.blob_lock);
+
        kfree(blob);
 }

@@ -4339,6 +4348,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
                return -EINVAL;

        drm_modeset_lock_all(dev);
+       mutex_lock(&dev->mode_config.blob_lock);
        blob = drm_property_blob_find(dev, out_resp->blob_id);
        if (!blob) {
                ret = -ENOENT;
@@ -4355,6 +4365,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
        out_resp->length = blob->length;

 done:
+       mutex_unlock(&dev->mode_config.blob_lock);
        drm_modeset_unlock_all(dev);
        return ret;
 }
@@ -5488,6 +5499,7 @@ void drm_mode_config_init(struct drm_device *dev)
        drm_modeset_lock_init(&dev->mode_config.connection_mutex);
        mutex_init(&dev->mode_config.idr_mutex);
        mutex_init(&dev->mode_config.fb_lock);
+       mutex_init(&dev->mode_config.blob_lock);
        INIT_LIST_HEAD(&dev->mode_config.fb_list);
        INIT_LIST_HEAD(&dev->mode_config.crtc_list);
        INIT_LIST_HEAD(&dev->mode_config.connector_list);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b009d70..43a3758 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1049,6 +1049,7 @@ struct drm_mode_group {
  * @poll_running: track polling status for this device
  * @output_poll_work: delayed work for polling in process context
  * @property_blob_list: list of all the blob property objects
+ * @blob_lock: mutex for blob property allocation and management
  * @*_property: core property tracking
  * @preferred_depth: preferred RBG pixel depth, used by fb helpers
  * @prefer_shadow: hint to userspace to prefer shadow-fb rendering
@@ -1104,6 +1105,8 @@ struct drm_mode_config {
        bool delayed_event;
        struct delayed_work output_poll_work;

+       struct mutex blob_lock;
+
        /* pointers to standard properties */
        struct list_head property_blob_list;
        struct drm_property *edid_property;
-- 
2.3.5

Reply via email to