summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fops.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2014-01-03 14:24:19 +0100
committerDavid Herrmann <dh.herrmann@gmail.com>2014-03-16 12:23:33 +0100
commit6796cb16c088905bf3af40548fda68c09e6f6ee5 (patch)
treed40162f17dad7b54ac63feaf62b7c84493556f5a /drivers/gpu/drm/drm_fops.c
parent31bbe16f6d88622d6731fa2cb4ab38d57d844ac1 (diff)
downloadlinux-6796cb16c088905bf3af40548fda68c09e6f6ee5.tar.gz
linux-6796cb16c088905bf3af40548fda68c09e6f6ee5.tar.bz2
linux-6796cb16c088905bf3af40548fda68c09e6f6ee5.zip
drm: use anon-inode instead of relying on cdevs
DRM drivers share a common address_space across all character-devices of a single DRM device. This allows simple buffer eviction and mapping-control. However, DRM core currently waits for the first ->open() on any char-dev to mark the underlying inode as backing inode of the device. This delayed initialization causes ugly conditions all over the place: if (dev->dev_mapping) do_sth(); To avoid delayed initialization and to stop reusing the inode of the char-dev, we allocate an anonymous inode for each DRM device and reset filp->f_mapping to it on ->open(). Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/drm_fops.c')
-rw-r--r--drivers/gpu/drm/drm_fops.c25
1 files changed, 3 insertions, 22 deletions
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 7f2af9aca038..147a84d9da9b 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -84,8 +84,6 @@ int drm_open(struct inode *inode, struct file *filp)
struct drm_minor *minor;
int retcode = 0;
int need_setup = 0;
- struct address_space *old_mapping;
- struct address_space *old_imapping;
minor = idr_find(&drm_minors_idr, minor_id);
if (!minor)
@@ -99,16 +97,9 @@ int drm_open(struct inode *inode, struct file *filp)
if (!dev->open_count++)
need_setup = 1;
- mutex_lock(&dev->struct_mutex);
- old_imapping = inode->i_mapping;
- old_mapping = dev->dev_mapping;
- if (old_mapping == NULL)
- dev->dev_mapping = &inode->i_data;
- /* ihold ensures nobody can remove inode with our i_data */
- ihold(container_of(dev->dev_mapping, struct inode, i_data));
- inode->i_mapping = dev->dev_mapping;
- filp->f_mapping = dev->dev_mapping;
- mutex_unlock(&dev->struct_mutex);
+
+ /* share address_space across all char-devs of a single device */
+ filp->f_mapping = dev->anon_inode->i_mapping;
retcode = drm_open_helper(inode, filp, dev);
if (retcode)
@@ -121,12 +112,6 @@ int drm_open(struct inode *inode, struct file *filp)
return 0;
err_undo:
- mutex_lock(&dev->struct_mutex);
- filp->f_mapping = old_imapping;
- inode->i_mapping = old_imapping;
- iput(container_of(dev->dev_mapping, struct inode, i_data));
- dev->dev_mapping = old_mapping;
- mutex_unlock(&dev->struct_mutex);
dev->open_count--;
return retcode;
}
@@ -434,7 +419,6 @@ int drm_lastclose(struct drm_device * dev)
drm_legacy_dma_takedown(dev);
- dev->dev_mapping = NULL;
mutex_unlock(&dev->struct_mutex);
drm_legacy_dev_reinit(dev);
@@ -549,9 +533,6 @@ int drm_release(struct inode *inode, struct file *filp)
}
}
- BUG_ON(dev->dev_mapping == NULL);
- iput(container_of(dev->dev_mapping, struct inode, i_data));
-
/* drop the reference held my the file priv */
if (file_priv->master)
drm_master_put(&file_priv->master);