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 01/11] drm: Move master pointer from drm_minor to drm_device
Date: Tue, 21 Jun 2016 10:54:12 +0200 [thread overview]
Message-ID: <1466499262-18717-1-git-send-email-daniel.vetter@ffwll.ch> (raw)
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.
v3: Rebase on top of Chris' oops fixes.
Cc: Julia Lawall <julia.lawall@lip6.fr>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v2)
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com> (v2)
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 | 9 ++++++++-
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(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index d858e69d337b..6bba6b9e9dcc 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);
}
out:
/* 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 e2d2543d5bd0..d6cfd5340d52 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -50,7 +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)
+ goto out_unlock;
seq_printf(m, "%s", dev->driver->name);
if (dev->dev)
@@ -60,6 +65,8 @@ int drm_name_info(struct seq_file *m, void *data)
if (dev->unique)
seq_printf(m, " unique=%s", dev->unique);
seq_printf(m, "\n");
+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 3b183c36801e..88f7b7e055f1 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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next reply other threads:[~2016-06-21 8:54 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-21 8:54 Daniel Vetter [this message]
2016-06-21 8:54 ` [PATCH 02/11] drm: Clean up drm_crtc.h Daniel Vetter
2016-06-21 8:54 ` [PATCH 03/11] drm: Use dev->name as fallback for dev->unique Daniel Vetter
2016-06-21 8:54 ` [PATCH 04/11] drm/vgem: Stop calling drm_drv_set_unique Daniel Vetter
2016-06-21 8:54 ` [PATCH 05/11] drm: Don't call drm_dev_set_unique from platform drivers Daniel Vetter
2016-06-21 8:54 ` [PATCH 06/11] drm: Nuke SET_UNIQUE ioctl Daniel Vetter
2016-06-21 8:54 ` [PATCH 07/11] drm: Lobotomize set_busid nonsense for !pci drivers Daniel Vetter
2016-06-21 12:08 ` [PATCH] " Daniel Vetter
2016-09-30 3:09 ` Regression: drm: Lobotomize set_busid nonsense for !pci drivers (a325725633c2) Laszlo Ersek
2016-09-30 8:28 ` Hans de Goede
2016-09-30 10:03 ` Laszlo Ersek
2016-09-30 10:35 ` Hans de Goede
2016-09-30 14:51 ` Laszlo Ersek
2016-09-30 14:59 ` Hans de Goede
2016-09-30 15:33 ` Laszlo Ersek
2016-09-30 16:38 ` Hans de Goede
2016-09-30 17:26 ` Laszlo Ersek
2016-10-03 11:34 ` Emil Velikov
2016-10-03 12:14 ` Laszlo Ersek
2016-10-03 12:46 ` Emil Velikov
2016-10-03 13:03 ` Laszlo Ersek
2016-10-03 14:15 ` Laszlo Ersek
2016-10-03 14:27 ` Laszlo Ersek
2016-10-03 15:00 ` Emil Velikov
2016-10-03 15:19 ` Laszlo Ersek
2016-10-03 19:12 ` Daniel Vetter
2016-10-03 19:36 ` Laszlo Ersek
2016-10-03 20:34 ` Daniel Vetter
2016-10-03 20:44 ` Laszlo Ersek
2016-10-04 7:43 ` Gerd Hoffmann
2016-10-05 6:34 ` Gerd Hoffmann
2016-10-05 10:30 ` Daniel Vetter
2016-10-05 12:43 ` Gerd Hoffmann
2016-10-05 13:02 ` Daniel Vetter
2016-09-30 9:55 ` Emil Velikov
2016-09-30 10:37 ` Emil Velikov
2016-06-21 8:54 ` [PATCH 08/11] drm: Refactor drop/set master code a bit Daniel Vetter
2016-06-21 12:20 ` [PATCH] " Daniel Vetter
2016-06-21 8:54 ` [PATCH 09/11] drm: Extract drm_is_current_master Daniel Vetter
2016-06-21 8:54 ` [PATCH 10/11] drm: Clear up master tracking booleans Daniel Vetter
2016-06-21 8:54 ` [PATCH 11/11] drm: document drm_auth.c Daniel Vetter
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=1466499262-18717-1-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 \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).