diff options
author | Ilija Hadzic <ihadzic@research.bell-labs.com> | 2012-05-15 16:40:10 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-07-25 14:09:30 +1000 |
commit | 949c4a34afacfe800fc442afac117aba15284962 (patch) | |
tree | ee7c6ebc5d8b05fbca1113b8c9147fbee7e26321 /drivers/gpu | |
parent | b97ce28e9f6d65a800e5c2ee3a2a99c7795bef65 (diff) | |
download | linux-949c4a34afacfe800fc442afac117aba15284962.tar.bz2 |
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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/drm_fops.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_gem.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_object.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ttm.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 5 |
5 files changed, 13 insertions, 18 deletions
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index d25a61739a7b..5062eec673f1 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -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; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 30f542316944..fe3f5a821b84 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -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); diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 6ecb2006e27e..1f77a5afc011 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -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) { diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 0881131a0388..5b71c716d83f 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -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) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 5d5632f5265b..4d9edead01ac 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -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; |