aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2014-12-17 07:34:22 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2015-03-24 07:50:58 -0400
commit76c4055f2c9a7ae556e96c1cadd82ee182b7d87e (patch)
treee9464ef16dd2638e6cc56a7d49f7eef34eda3bdd /drivers/gpu/drm/omapdrm
parent8519c62ce610e512722d1d8e3991c02cca59010c (diff)
drm/omap: fix race condition with dev->obj_list
omap_gem_objects are added to dev->obj_list in omap_gem_new, and removed in omap_gem_free_object. Unfortunately there's no locking for dev->obj_list, which eventually leads to a crash: WARNING: CPU: 1 PID: 1123 at lib/list_debug.c:59 __list_del_entry+0xa4/0xe0() list_del corruption. prev->next should be e9281344, but was ea722b84 Add a spinlock to protect dev->obj_list. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c5
3 files changed, 9 insertions, 0 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index c4c237317901..c6980985884b 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -491,6 +491,7 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
491 491
492 priv->wq = alloc_ordered_workqueue("omapdrm", 0); 492 priv->wq = alloc_ordered_workqueue("omapdrm", 0);
493 493
494 spin_lock_init(&priv->list_lock);
494 INIT_LIST_HEAD(&priv->obj_list); 495 INIT_LIST_HEAD(&priv->obj_list);
495 496
496 omap_gem_init(dev); 497 omap_gem_init(dev);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 57e11c1f589f..b31c79f15aed 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -105,6 +105,9 @@ struct omap_drm_private {
105 105
106 struct workqueue_struct *wq; 106 struct workqueue_struct *wq;
107 107
108 /* lock for obj_list below */
109 spinlock_t list_lock;
110
108 /* list of GEM objects: */ 111 /* list of GEM objects: */
109 struct list_head obj_list; 112 struct list_head obj_list;
110 113
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index d37ee756a0b1..e9718b99a8a9 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -1273,13 +1273,16 @@ unlock:
1273void omap_gem_free_object(struct drm_gem_object *obj) 1273void omap_gem_free_object(struct drm_gem_object *obj)
1274{ 1274{
1275 struct drm_device *dev = obj->dev; 1275 struct drm_device *dev = obj->dev;
1276 struct omap_drm_private *priv = dev->dev_private;
1276 struct omap_gem_object *omap_obj = to_omap_bo(obj); 1277 struct omap_gem_object *omap_obj = to_omap_bo(obj);
1277 1278
1278 evict(obj); 1279 evict(obj);
1279 1280
1280 WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 1281 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
1281 1282
1283 spin_lock(&priv->list_lock);
1282 list_del(&omap_obj->mm_list); 1284 list_del(&omap_obj->mm_list);
1285 spin_unlock(&priv->list_lock);
1283 1286
1284 drm_gem_free_mmap_offset(obj); 1287 drm_gem_free_mmap_offset(obj);
1285 1288
@@ -1377,7 +1380,9 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
1377 if (!omap_obj) 1380 if (!omap_obj)
1378 goto fail; 1381 goto fail;
1379 1382
1383 spin_lock(&priv->list_lock);
1380 list_add(&omap_obj->mm_list, &priv->obj_list); 1384 list_add(&omap_obj->mm_list, &priv->obj_list);
1385 spin_unlock(&priv->list_lock);
1381 1386
1382 obj = &omap_obj->base; 1387 obj = &omap_obj->base;
1383 1388