mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 07:00:48 +00:00
drm: track dev_mapping in more robust and flexible way
Setting dev_mapping (pointer to the address_space structure used for memory mappings) to the address_space of the first opener's inode and then failing if other openers come in through a different inode has a few restrictions that are eliminated by this patch. If we already have valid dev_mapping and we spot an opener with different i_node, we force its i_mapping pointer to the already established address_space structure (first opener's inode). This will make all mappings from drm device hang off the same address_space object. Some benefits (things that now work and didn't work before) of this patch are: * user space can mknod and use any number of device nodes and they will all work fine as long as the major device number is that of the drm module. * user space can even remove the first opener's device nodes and mknod the new one and the applications and windowing system will still work. * GPU drivers can safely assume that dev->dev_mapping is correct address_space and just blindly copy it into their (private) bdev.dev_mapping For reference, some discussion that lead to this patch can be found here: http://lists.freedesktop.org/archives/dri-devel/2012-April/022283.html Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
b97ce28e9f
commit
949c4a34af
@ -140,12 +140,12 @@ int drm_open(struct inode *inode, struct file *filp)
|
||||
}
|
||||
if (!retcode) {
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
if (minor->type == DRM_MINOR_LEGACY) {
|
||||
if (dev->dev_mapping == NULL)
|
||||
dev->dev_mapping = inode->i_mapping;
|
||||
else if (dev->dev_mapping != inode->i_mapping)
|
||||
retcode = -ENODEV;
|
||||
}
|
||||
if (dev->dev_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);
|
||||
}
|
||||
|
||||
@ -509,6 +509,9 @@ 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 */
|
||||
drm_master_put(&file_priv->master);
|
||||
file_priv->is_master = 0;
|
||||
|
@ -207,8 +207,7 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
|
||||
struct nouveau_bo *nvbo = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
|
||||
dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;
|
||||
dev_priv->ttm.bdev.dev_mapping = dev->dev_mapping;
|
||||
|
||||
if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) {
|
||||
NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags);
|
||||
|
@ -115,9 +115,7 @@ int radeon_bo_create(struct radeon_device *rdev,
|
||||
|
||||
size = ALIGN(size, PAGE_SIZE);
|
||||
|
||||
if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
|
||||
rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping;
|
||||
}
|
||||
rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping;
|
||||
if (kernel) {
|
||||
type = ttm_bo_type_kernel;
|
||||
} else if (sg) {
|
||||
|
@ -734,9 +734,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
|
||||
}
|
||||
DRM_INFO("radeon: %uM of GTT memory ready.\n",
|
||||
(unsigned)(rdev->mc.gtt_size / (1024 * 1024)));
|
||||
if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
|
||||
rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping;
|
||||
}
|
||||
rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping;
|
||||
|
||||
r = radeon_ttm_debugfs_init(rdev);
|
||||
if (r) {
|
||||
|
@ -769,10 +769,7 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv)
|
||||
goto out_no_tfile;
|
||||
|
||||
file_priv->driver_priv = vmw_fp;
|
||||
|
||||
if (unlikely(dev_priv->bdev.dev_mapping == NULL))
|
||||
dev_priv->bdev.dev_mapping =
|
||||
file_priv->filp->f_path.dentry->d_inode->i_mapping;
|
||||
dev_priv->bdev.dev_mapping = dev->dev_mapping;
|
||||
|
||||
return 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user