aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-01-19 02:17:58 -0500
committerDave Airlie <airlied@redhat.com>2009-01-19 02:17:58 -0500
commitc1ff85d97708550e634fb6fa099c463db90fc40d (patch)
tree58d06ba7fb375232ec614bc78db39faceb7898c6 /drivers/gpu
parent1de9e8e70f5acc441550ca75433563d91b269bbe (diff)
drm: fix leak of device mappings since multi-master changes.
Device maps now contain a link to the master that created them, so when cleaning up the master, remove any maps that are connected to it. Also delete any remaining maps at driver unload time. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/drm_drv.c4
-rw-r--r--drivers/gpu/drm/drm_stub.c8
2 files changed, 12 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 5ff88d952226..14c7a23dc157 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -294,6 +294,7 @@ EXPORT_SYMBOL(drm_init);
294 */ 294 */
295static void drm_cleanup(struct drm_device * dev) 295static void drm_cleanup(struct drm_device * dev)
296{ 296{
297 struct drm_map_list *r_list, *list_temp;
297 DRM_DEBUG("\n"); 298 DRM_DEBUG("\n");
298 299
299 if (!dev) { 300 if (!dev) {
@@ -325,6 +326,9 @@ static void drm_cleanup(struct drm_device * dev)
325 drm_ht_remove(&dev->map_hash); 326 drm_ht_remove(&dev->map_hash);
326 drm_ctxbitmap_cleanup(dev); 327 drm_ctxbitmap_cleanup(dev);
327 328
329 list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
330 drm_rmmap(dev, r_list->map);
331
328 if (drm_core_check_feature(dev, DRIVER_MODESET)) 332 if (drm_core_check_feature(dev, DRIVER_MODESET))
329 drm_put_minor(&dev->control); 333 drm_put_minor(&dev->control);
330 334
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 5ca132afa4f2..46bb923b097c 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -118,12 +118,20 @@ static void drm_master_destroy(struct kref *kref)
118 struct drm_master *master = container_of(kref, struct drm_master, refcount); 118 struct drm_master *master = container_of(kref, struct drm_master, refcount);
119 struct drm_magic_entry *pt, *next; 119 struct drm_magic_entry *pt, *next;
120 struct drm_device *dev = master->minor->dev; 120 struct drm_device *dev = master->minor->dev;
121 struct drm_map_list *r_list, *list_temp;
121 122
122 list_del(&master->head); 123 list_del(&master->head);
123 124
124 if (dev->driver->master_destroy) 125 if (dev->driver->master_destroy)
125 dev->driver->master_destroy(dev, master); 126 dev->driver->master_destroy(dev, master);
126 127
128 list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
129 if (r_list->master == master) {
130 drm_rmmap_locked(dev, r_list->map);
131 r_list = NULL;
132 }
133 }
134
127 if (master->unique) { 135 if (master->unique) {
128 drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER); 136 drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER);
129 master->unique = NULL; 137 master->unique = NULL;