]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
drm/omap: gem: Fix mm_list locking
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 25 May 2018 16:39:24 +0000 (19:39 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Oct 2018 23:59:13 +0000 (16:59 -0700)
[ Upstream commit 5117bd898e8c0a31e8ab3a9b8523aecf0706e997 ]

- None of the list walkings where protected.

- Switch to a mutex since the list walking at device resume time can
  sleep when pinning buffers through the tiler.

Only thing we need to be careful with here is that while we walk the
list we can't unreference any gem objects, since the final unref would
result in a recursive deadlock. But the only functions that walk the
list is the device resume and debugfs dumping, so all safe.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/omapdrm/omap_debugfs.c
drivers/gpu/drm/omapdrm/omap_drv.c
drivers/gpu/drm/omapdrm/omap_drv.h
drivers/gpu/drm/omapdrm/omap_gem.c

index b42e286616b00b894b99e133c06d56b4b24db9be..84da7a5b84f329895145c11b6508b1f8f8af2fd5 100644 (file)
@@ -37,7 +37,9 @@ static int gem_show(struct seq_file *m, void *arg)
                return ret;
 
        seq_printf(m, "All Objects:\n");
+       mutex_lock(&priv->list_lock);
        omap_gem_describe_objects(&priv->obj_list, m);
+       mutex_unlock(&priv->list_lock);
 
        mutex_unlock(&dev->struct_mutex);
 
index ef3b0e3571ec860ee64c3f75d15c08c00b83c011..5fcf9eaf3eafeb5fe01c5719e7f9ccf931511309 100644 (file)
@@ -540,7 +540,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
        priv->omaprev = soc ? (unsigned int)soc->data : 0;
        priv->wq = alloc_ordered_workqueue("omapdrm", 0);
 
-       spin_lock_init(&priv->list_lock);
+       mutex_init(&priv->list_lock);
        INIT_LIST_HEAD(&priv->obj_list);
 
        /* Allocate and initialize the DRM device. */
index 6eaee4df45594c8d23ba3df0af07244e07c92d6c..f27c8e216adf894f8180f40b0c885b2c683ccd86 100644 (file)
@@ -71,7 +71,7 @@ struct omap_drm_private {
        struct workqueue_struct *wq;
 
        /* lock for obj_list below */
-       spinlock_t list_lock;
+       struct mutex list_lock;
 
        /* list of GEM objects: */
        struct list_head obj_list;
index 17a53d2079781c00ad743a3c0da9ac271024d589..7a029b892a37b4ba10952f9f8bedd118d15f372e 100644 (file)
@@ -1001,6 +1001,7 @@ int omap_gem_resume(struct drm_device *dev)
        struct omap_gem_object *omap_obj;
        int ret = 0;
 
+       mutex_lock(&priv->list_lock);
        list_for_each_entry(omap_obj, &priv->obj_list, mm_list) {
                if (omap_obj->block) {
                        struct drm_gem_object *obj = &omap_obj->base;
@@ -1012,12 +1013,14 @@ int omap_gem_resume(struct drm_device *dev)
                                        omap_obj->roll, true);
                        if (ret) {
                                dev_err(dev->dev, "could not repin: %d\n", ret);
-                               return ret;
+                               goto done;
                        }
                }
        }
 
-       return 0;
+done:
+       mutex_unlock(&priv->list_lock);
+       return ret;
 }
 #endif
 
@@ -1085,9 +1088,9 @@ void omap_gem_free_object(struct drm_gem_object *obj)
 
        WARN_ON(!mutex_is_locked(&dev->struct_mutex));
 
-       spin_lock(&priv->list_lock);
+       mutex_lock(&priv->list_lock);
        list_del(&omap_obj->mm_list);
-       spin_unlock(&priv->list_lock);
+       mutex_unlock(&priv->list_lock);
 
        /* this means the object is still pinned.. which really should
         * not happen.  I think..
@@ -1206,9 +1209,9 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
                        goto err_release;
        }
 
-       spin_lock(&priv->list_lock);
+       mutex_lock(&priv->list_lock);
        list_add(&omap_obj->mm_list, &priv->obj_list);
-       spin_unlock(&priv->list_lock);
+       mutex_unlock(&priv->list_lock);
 
        return obj;