]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.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)
committerJuerg Haefliger <juergh@canonical.com>
Wed, 24 Jul 2019 01:51:42 +0000 (19:51 -0600)
BugLink: https://bugs.launchpad.net/bugs/1836287
[ 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>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
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 19b716745623ac9f9539307149e634b1efaed454..e7aa52c1316944f13bb840f764e395af8fc88434 100644 (file)
@@ -39,7 +39,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 cdf5b0601ebabee12cb876c2d632bc59b18ad66d..cc75f322aa90802bd462d60565fb40d765651c5d 100644 (file)
@@ -580,7 +580,7 @@ static int pdev_probe(struct platform_device *pdev)
        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 4bd1e9070b3184428058331bb31a4ec1f96924c6..dd790c7fa1a3a1bacdd4f082dddaf521f5a85504 100644 (file)
@@ -68,7 +68,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 5c5c86ddd6f4777a10f5b326d2df34138ba33cf8..e1ffdb780929aae71eacc4eb8afa6fccad603d0b 100644 (file)
@@ -1003,6 +1003,7 @@ int omap_gem_resume(struct 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;
@@ -1013,12 +1014,14 @@ int omap_gem_resume(struct device *dev)
                                        omap_obj->roll, true);
                        if (ret) {
                                dev_err(dev, "could not repin: %d\n", ret);
-                               return ret;
+                               goto done;
                        }
                }
        }
 
-       return 0;
+done:
+       mutex_unlock(&priv->list_lock);
+       return ret;
 }
 #endif
 
@@ -1086,9 +1089,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..
@@ -1207,9 +1210,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;