Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 949c4a34 authored by Ilija Hadzic's avatar Ilija Hadzic Committed by Dave Airlie
Browse files

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: default avatarIlija Hadzic <ihadzic@research.bell-labs.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent b97ce28e
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -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;
		}
			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;
+1 −2
Original line number Diff line number Diff line
@@ -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);
+1 −3
Original line number Diff line number Diff line
@@ -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;
	}
	if (kernel) {
		type = ttm_bo_type_kernel;
	} else if (sg) {
+1 −3
Original line number Diff line number Diff line
@@ -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;
	}

	r = radeon_ttm_debugfs_init(rdev);
	if (r) {
+1 −4
Original line number Diff line number Diff line
@@ -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;