[PATCH 08/11] drm: Refactor drop/set master code a bit

Daniel Vetter daniel.vetter at ffwll.ch
Tue Jun 21 08:54:19 UTC 2016


File open/set_maseter ioctl and file close/drop_master ioctl share the
same master handling code. Extract it.

Note that vmwgfx's master_set callback needs to know whether the
master is a new one or has been used already, so thread this through.
On the close/drop side a similar parameter existed, but wasnt used.
Drop it to simplify the flow.

v2: Try to make it not leak so much (Emil).

Cc: Emil Velikov <emil.l.velikov at gmail.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Thomas Hellstrom <thellstrom at vmware.com>
Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
---
 drivers/gpu/drm/drm_auth.c          | 80 +++++++++++++++++++------------------
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |  3 +-
 include/drm/drmP.h                  |  3 +-
 3 files changed, 44 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 6bba6b9e9dcc..2794a4f3a105 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -110,6 +110,24 @@ static struct drm_master *drm_master_create(struct drm_device *dev)
 	return master;
 }
 
+static int drm_set_master(struct drm_device *dev, struct drm_file *fpriv,
+			  bool new_master)
+{
+	int ret = 0;
+
+	dev->master = drm_master_get(fpriv->master);
+	fpriv->is_master = 1;
+	if (dev->driver->master_set) {
+		ret = dev->driver->master_set(dev, fpriv, new_master);
+		if (unlikely(ret != 0)) {
+			fpriv->is_master = 0;
+			drm_master_put(&dev->master);
+		}
+	}
+
+	return ret;
+}
+
 /*
  * drm_new_set_master - Allocate a new master object and become master for the
  * associated master realm.
@@ -127,37 +145,32 @@ 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 */
-	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(dev->master);
+	fpriv->master = drm_master_create(dev);
+	if (!fpriv->master) {
+		fpriv->master = old_master;
+		return -ENOMEM;
+	}
 
 	if (dev->driver->master_create) {
 		ret = dev->driver->master_create(dev, fpriv->master);
 		if (ret)
 			goto out_err;
 	}
-	if (dev->driver->master_set) {
-		ret = dev->driver->master_set(dev, fpriv, true);
-		if (ret)
-			goto out_err;
-	}
-
-	fpriv->is_master = 1;
 	fpriv->allowed_master = 1;
 	fpriv->authenticated = 1;
+
+	ret = drm_set_master(dev, fpriv, true);
+	if (ret)
+		goto out_err;
+
 	if (old_master)
 		drm_master_put(&old_master);
 
 	return 0;
 
 out_err:
-	/* drop both references and restore old master on failure */
-	drm_master_put(&dev->master);
+	/* drop references and restore old master on failure */
 	drm_master_put(&fpriv->master);
 	fpriv->master = old_master;
 
@@ -188,21 +201,21 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 		goto out_unlock;
 	}
 
-	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(&dev->master);
-		}
-	}
-
+	ret = drm_set_master(dev, file_priv, false);
 out_unlock:
 	mutex_unlock(&dev->master_mutex);
 	return ret;
 }
 
+static void drm_drop_master(struct drm_device *dev,
+			    struct drm_file *fpriv)
+{
+	if (dev->driver->master_drop)
+		dev->driver->master_drop(dev, fpriv);
+	drm_master_put(&dev->master);
+	fpriv->is_master = 0;
+}
+
 int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv)
 {
@@ -216,11 +229,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 		goto out_unlock;
 
 	ret = 0;
-	if (dev->driver->master_drop)
-		dev->driver->master_drop(dev, file_priv, false);
-	drm_master_put(&dev->master);
-	file_priv->is_master = 0;
-
+	drm_drop_master(dev, file_priv);
 out_unlock:
 	mutex_unlock(&dev->master_mutex);
 	return ret;
@@ -271,17 +280,12 @@ void drm_master_release(struct drm_file *file_priv)
 		mutex_unlock(&dev->struct_mutex);
 	}
 
-	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(&dev->master);
-	}
+	if (dev->master == file_priv->master)
+		drm_drop_master(dev, file_priv);
 out:
 	/* drop the master reference held by the file priv */
 	if (file_priv->master)
 		drm_master_put(&file_priv->master);
-	file_priv->is_master = 0;
 	mutex_unlock(&dev->master_mutex);
 }
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 9fcd8200d485..35eedc9d44fa 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1228,8 +1228,7 @@ static int vmw_master_set(struct drm_device *dev,
 }
 
 static void vmw_master_drop(struct drm_device *dev,
-			    struct drm_file *file_priv,
-			    bool from_release)
+			    struct drm_file *file_priv)
 {
 	struct vmw_private *dev_priv = vmw_priv(dev);
 	struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 179bdb228ecb..0f9046de0418 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -573,8 +573,7 @@ struct drm_driver {
 
 	int (*master_set)(struct drm_device *dev, struct drm_file *file_priv,
 			  bool from_open);
-	void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv,
-			    bool from_release);
+	void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv);
 
 	int (*debugfs_init)(struct drm_minor *minor);
 	void (*debugfs_cleanup)(struct drm_minor *minor);
-- 
2.8.1



More information about the dri-devel mailing list