浏览代码

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>
Dave Airlie 16 年之前
父节点
当前提交
c1ff85d977
共有 2 个文件被更改,包括 12 次插入0 次删除
  1. 4 0
      drivers/gpu/drm/drm_drv.c
  2. 8 0
      drivers/gpu/drm/drm_stub.c

+ 4 - 0
drivers/gpu/drm/drm_drv.c

@@ -294,6 +294,7 @@ EXPORT_SYMBOL(drm_init);
  */
 static void drm_cleanup(struct drm_device * dev)
 {
+	struct drm_map_list *r_list, *list_temp;
 	DRM_DEBUG("\n");
 
 	if (!dev) {
@@ -325,6 +326,9 @@ static void drm_cleanup(struct drm_device * dev)
 	drm_ht_remove(&dev->map_hash);
 	drm_ctxbitmap_cleanup(dev);
 
+	list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
+		drm_rmmap(dev, r_list->map);
+
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		drm_put_minor(&dev->control);
 

+ 8 - 0
drivers/gpu/drm/drm_stub.c

@@ -118,12 +118,20 @@ static void drm_master_destroy(struct kref *kref)
 	struct drm_master *master = container_of(kref, struct drm_master, refcount);
 	struct drm_magic_entry *pt, *next;
 	struct drm_device *dev = master->minor->dev;
+	struct drm_map_list *r_list, *list_temp;
 
 	list_del(&master->head);
 
 	if (dev->driver->master_destroy)
 		dev->driver->master_destroy(dev, master);
 
+	list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
+		if (r_list->master == master) {
+			drm_rmmap_locked(dev, r_list->map);
+			r_list = NULL;
+		}
+	}
+
 	if (master->unique) {
 		drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER);
 		master->unique = NULL;