All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel.vetter@ffwll.ch>
To: DRI Development <dri-devel@lists.freedesktop.org>
Cc: Daniel Vetter <daniel.vetter@intel.com>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	Intel Graphics Development <intel-gfx@lists.freedesktop.org>,
	Julia Lawall <julia.lawall@lip6.fr>
Subject: [PATCH 12/14] drm: Move master pointer from drm_minor to drm_device
Date: Tue, 14 Jun 2016 20:51:07 +0200	[thread overview]
Message-ID: <1465930269-7883-13-git-send-email-daniel.vetter@ffwll.ch> (raw)
In-Reply-To: <1465930269-7883-1-git-send-email-daniel.vetter@ffwll.ch>

There can only be one current master, and it's for the overall device.
Render/control minors don't support master-based auth at all.

This simplifies the master logic a lot, at least in my eyes: All these
additional pointer chases are just confusing.

While doing the conversion I spotted some locking fail:
- drm_lock/drm_auth check dev->master without holding the
  master_mutex. This is fallout from

  commit c996fd0b956450563454e7ccc97a82ca31f9d043
  Author: Thomas Hellstrom <thellstrom@vmware.com>
  Date:   Tue Feb 25 19:57:44 2014 +0100

      drm: Protect the master management with a drm_device::master_mutex v3

  but I honestly don't care one bit about those old legacy drivers
  using this.

- debugfs name info should just grab master_mutex.

- And the fbdev helper looked at it to figure out whether someone is
  using KMS. We just need a consistent value, so READ_ONCE. Aside: We
  should probably check if anyone has opened a control node too, but I
  guess current userspace doesn't really do that yet.

v2: Balance locking, reported by Julia.

Cc: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_auth.c      | 26 +++++++++++++-------------
 drivers/gpu/drm/drm_bufs.c      |  8 ++++----
 drivers/gpu/drm/drm_fb_helper.c |  2 +-
 drivers/gpu/drm/drm_info.c      | 10 ++++++++--
 drivers/gpu/drm/drm_lock.c      |  2 +-
 drivers/gpu/drm/sis/sis_mm.c    |  2 +-
 drivers/gpu/drm/via/via_mm.c    |  2 +-
 include/drm/drmP.h              |  9 +++++----
 8 files changed, 34 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 94761e4bd1e5..fcadd8e1de28 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -128,13 +128,13 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
 	lockdep_assert_held_once(&dev->master_mutex);
 
 	/* create a new master */
-	fpriv->minor->master = drm_master_create(fpriv->minor->dev);
-	if (!fpriv->minor->master)
+	dev->master = drm_master_create(dev);
+	if (!dev->master)
 		return -ENOMEM;
 
 	/* take another reference for the copy in the local file priv */
 	old_master = fpriv->master;
-	fpriv->master = drm_master_get(fpriv->minor->master);
+	fpriv->master = drm_master_get(dev->master);
 
 	if (dev->driver->master_create) {
 		ret = dev->driver->master_create(dev, fpriv->master);
@@ -157,7 +157,7 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
 
 out_err:
 	/* drop both references and restore old master on failure */
-	drm_master_put(&fpriv->minor->master);
+	drm_master_put(&dev->master);
 	drm_master_put(&fpriv->master);
 	fpriv->master = old_master;
 
@@ -173,7 +173,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 	if (file_priv->is_master)
 		goto out_unlock;
 
-	if (file_priv->minor->master) {
+	if (dev->master) {
 		ret = -EINVAL;
 		goto out_unlock;
 	}
@@ -188,13 +188,13 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 		goto out_unlock;
 	}
 
-	file_priv->minor->master = drm_master_get(file_priv->master);
+	dev->master = drm_master_get(file_priv->master);
 	file_priv->is_master = 1;
 	if (dev->driver->master_set) {
 		ret = dev->driver->master_set(dev, file_priv, false);
 		if (unlikely(ret != 0)) {
 			file_priv->is_master = 0;
-			drm_master_put(&file_priv->minor->master);
+			drm_master_put(&dev->master);
 		}
 	}
 
@@ -212,13 +212,13 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 	if (!file_priv->is_master)
 		goto out_unlock;
 
-	if (!file_priv->minor->master)
+	if (!dev->master)
 		goto out_unlock;
 
 	ret = 0;
 	if (dev->driver->master_drop)
 		dev->driver->master_drop(dev, file_priv, false);
-	drm_master_put(&file_priv->minor->master);
+	drm_master_put(&dev->master);
 	file_priv->is_master = 0;
 
 out_unlock:
@@ -234,10 +234,10 @@ int drm_master_open(struct drm_file *file_priv)
 	/* if there is no current master make this fd it, but do not create
 	 * any master object for render clients */
 	mutex_lock(&dev->master_mutex);
-	if (!file_priv->minor->master)
+	if (!dev->master)
 		ret = drm_new_set_master(dev, file_priv);
 	else
-		file_priv->master = drm_master_get(file_priv->minor->master);
+		file_priv->master = drm_master_get(dev->master);
 	mutex_unlock(&dev->master_mutex);
 
 	return ret;
@@ -271,11 +271,11 @@ void drm_master_release(struct drm_file *file_priv)
 		mutex_unlock(&dev->struct_mutex);
 	}
 
-	if (file_priv->minor->master == file_priv->master) {
+	if (dev->master == file_priv->master) {
 		/* drop the reference held my the minor */
 		if (dev->driver->master_drop)
 			dev->driver->master_drop(dev, file_priv, true);
-		drm_master_put(&file_priv->minor->master);
+		drm_master_put(&dev->master);
 	}
 
 	/* drop the master reference held by the file priv */
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 9b34158c0f77..c3a12cd8bd0d 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -51,7 +51,7 @@ static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
 		 */
 		if (!entry->map ||
 		    map->type != entry->map->type ||
-		    entry->master != dev->primary->master)
+		    entry->master != dev->master)
 			continue;
 		switch (map->type) {
 		case _DRM_SHM:
@@ -245,12 +245,12 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
 		map->offset = (unsigned long)map->handle;
 		if (map->flags & _DRM_CONTAINS_LOCK) {
 			/* Prevent a 2nd X Server from creating a 2nd lock */
-			if (dev->primary->master->lock.hw_lock != NULL) {
+			if (dev->master->lock.hw_lock != NULL) {
 				vfree(map->handle);
 				kfree(map);
 				return -EBUSY;
 			}
-			dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle;	/* Pointer to lock */
+			dev->sigdata.lock = dev->master->lock.hw_lock = map->handle;	/* Pointer to lock */
 		}
 		break;
 	case _DRM_AGP: {
@@ -356,7 +356,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
 	mutex_unlock(&dev->struct_mutex);
 
 	if (!(map->flags & _DRM_DRIVER))
-		list->master = dev->primary->master;
+		list->master = dev->master;
 	*maplist = list;
 	return 0;
 }
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 0bac5246e5a7..0a06f9120b5a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -464,7 +464,7 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
 
 	/* Sometimes user space wants everything disabled, so don't steal the
 	 * display if there's a master. */
-	if (dev->primary->master)
+	if (READ_ONCE(dev->master))
 		return false;
 
 	drm_for_each_crtc(crtc, dev) {
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 0090d5987801..24c80dd13837 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -50,9 +50,12 @@ int drm_name_info(struct seq_file *m, void *data)
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
 	struct drm_minor *minor = node->minor;
 	struct drm_device *dev = minor->dev;
-	struct drm_master *master = minor->master;
+	struct drm_master *master;
+
+	mutex_lock(&dev->master_mutex);
+	master = dev->master;
 	if (!master)
-		return 0;
+		goto out_unlock;
 
 	if (master->unique) {
 		seq_printf(m, "%s %s %s\n",
@@ -62,6 +65,9 @@ int drm_name_info(struct seq_file *m, void *data)
 		seq_printf(m, "%s %s\n",
 			   dev->driver->name, dev_name(dev->dev));
 	}
+out_unlock:
+	mutex_unlock(&dev->master_mutex);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index 0fb8f9e73486..ae0a4d39deec 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -334,7 +334,7 @@ void drm_legacy_lock_release(struct drm_device *dev, struct file *filp)
 	struct drm_file *file_priv = filp->private_data;
 
 	/* if the master has gone away we can't do anything with the lock */
-	if (!file_priv->minor->master)
+	if (!dev->master)
 		return;
 
 	if (drm_legacy_i_have_hw_lock(dev, file_priv)) {
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
index 93ad8a5704d1..03defda77766 100644
--- a/drivers/gpu/drm/sis/sis_mm.c
+++ b/drivers/gpu/drm/sis/sis_mm.c
@@ -316,7 +316,7 @@ void sis_reclaim_buffers_locked(struct drm_device *dev,
 	struct sis_file_private *file_priv = file->driver_priv;
 	struct sis_memblock *entry, *next;
 
-	if (!(file->minor->master && file->master->lock.hw_lock))
+	if (!(dev->master && file->master->lock.hw_lock))
 		return;
 
 	drm_legacy_idlelock_take(&file->master->lock);
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index 4f20742e7788..a04ef1c992d9 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -208,7 +208,7 @@ void via_reclaim_buffers_locked(struct drm_device *dev,
 	struct via_file_private *file_priv = file->driver_priv;
 	struct via_memblock *entry, *next;
 
-	if (!(file->minor->master && file->master->lock.hw_lock))
+	if (!(dev->master && file->master->lock.hw_lock))
 		return;
 
 	drm_legacy_idlelock_take(&file->master->lock);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index e8788d7b29dc..62e0e70cb5a2 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -336,7 +336,7 @@ struct drm_file {
 	void *driver_priv;
 
 	struct drm_master *master; /* master this node is currently associated with
-				      N.B. not always minor->master */
+				      N.B. not always dev->master */
 	/**
 	 * fbs - List of framebuffers associated with this file.
 	 *
@@ -708,9 +708,6 @@ struct drm_minor {
 
 	struct list_head debugfs_list;
 	struct mutex debugfs_lock; /* Protects debugfs_list. */
-
-	/* currently active master for this node. Protected by master_mutex */
-	struct drm_master *master;
 };
 
 
@@ -759,6 +756,10 @@ struct drm_device {
 	struct drm_minor *control;		/**< Control node */
 	struct drm_minor *primary;		/**< Primary node */
 	struct drm_minor *render;		/**< Render node */
+
+	/* currently active master for this device. Protected by master_mutex */
+	struct drm_master *master;
+
 	atomic_t unplugged;			/**< Flag whether dev is dead */
 	struct inode *anon_inode;		/**< inode for private address-space */
 	char *unique;				/**< unique name of the device */
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2016-06-14 18:51 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-14 18:50 [PATCH 00/14] Cruft removal around drm_master Daniel Vetter
2016-06-14 18:50 ` [PATCH 01/14] drm: Nuke legacy maps debugfs files Daniel Vetter
2016-06-15 11:23   ` Chris Wilson
2016-06-15 12:00   ` Emil Velikov
2016-06-14 18:50 ` [PATCH 02/14] drm: Hide hw.lock cleanup in filp->release better Daniel Vetter
2016-06-15 11:26   ` [Intel-gfx] " Chris Wilson
2016-06-15 12:10   ` Emil Velikov
2016-06-14 18:50 ` [PATCH 03/14] drm: Link directly from drm_master to drm_device Daniel Vetter
2016-06-15 11:29   ` Chris Wilson
2016-06-15 12:50   ` [Intel-gfx] " Emil Velikov
2016-06-15 15:45     ` Daniel Vetter
2016-06-16 20:04       ` Emil Velikov
2016-06-14 18:50 ` [PATCH 04/14] drm: Move master functions into drm_auth.c Daniel Vetter
2016-06-15 11:31   ` Chris Wilson
2016-06-15 15:47     ` Daniel Vetter
2016-06-14 18:51 ` [PATCH 05/14] drm: Extract drm_master_open Daniel Vetter
2016-06-15 11:41   ` [Intel-gfx] " Chris Wilson
2016-06-14 18:51 ` [PATCH 06/14] drm: Extract drm_master_relase Daniel Vetter
2016-06-15 11:43   ` [Intel-gfx] " Chris Wilson
2016-06-16  8:18     ` Daniel Vetter
2016-06-14 18:51 ` [PATCH 07/14] drm: Only do the hw.lock cleanup in master_relase for !MODESET Daniel Vetter
2016-06-15 11:48   ` Chris Wilson
2016-06-15 15:49     ` [Intel-gfx] " Daniel Vetter
2016-06-14 18:51 ` [PATCH 08/14] drm: Move authmagic cleanup into drm_master_release Daniel Vetter
2016-06-15 11:51   ` Chris Wilson
2016-06-14 18:51 ` [PATCH 09/14] drm: Protect authmagic with master_mutex Daniel Vetter
2016-06-15 11:54   ` [Intel-gfx] " Chris Wilson
2016-06-15 15:52     ` Daniel Vetter
2016-06-14 18:51 ` [PATCH 10/14] drm: Mark authmagic ioctls as unlocked Daniel Vetter
2016-06-15 11:55   ` [Intel-gfx] " Chris Wilson
2016-06-14 18:51 ` [PATCH 11/14] drm: Mark set/drop master ioctl " Daniel Vetter
2016-06-15 11:56   ` [Intel-gfx] " Chris Wilson
2016-06-14 18:51 ` Daniel Vetter [this message]
2016-06-15 12:10   ` [Intel-gfx] [PATCH 12/14] drm: Move master pointer from drm_minor to drm_device Chris Wilson
2016-06-15 16:01     ` Daniel Vetter
2016-06-15 16:33       ` Chris Wilson
2016-06-15 19:54         ` [Intel-gfx] " Daniel Vetter
2016-06-14 18:51 ` [PATCH 13/14] drm: Clean up drm_crtc.h Daniel Vetter
2016-06-14 18:51 ` [PATCH 14/14] drm: Use dev->name as fallback for dev->unique Daniel Vetter
2016-06-15  5:42 ` ✓ Ro.CI.BAT: success for Cruft removal around drm_master Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1465930269-7883-13-git-send-email-daniel.vetter@ffwll.ch \
    --to=daniel.vetter@ffwll.ch \
    --cc=daniel.vetter@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=julia.lawall@lip6.fr \
    --subject='Re: [PATCH 12/14] drm: Move master pointer from drm_minor to drm_device' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.