drm: Extract drm_master_open
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 14 Jun 2016 18:51:00 +0000 (20:51 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 16 Jun 2016 08:17:42 +0000 (10:17 +0200)
And pull out the primary_client check to make it really obvious that
this can't happen on control/render nodes. Bonus that we can avoid the
master lock in this case.

v2: Don't leak locks on error path (and simplify control flow while
at it), reported by Julia.

Cc: Julia Lawall <julia.lawall@lip6.fr>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1465930269-7883-6-git-send-email-daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_auth.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_internal.h

index 1d314ae1356042a260aed488c1f577ac93f850f7..9c1e2081cd58bd126b9afb6a307921cd23dc847e 100644 (file)
@@ -120,7 +120,7 @@ static struct drm_master *drm_master_create(struct drm_device *dev)
  * This function must be called with dev::struct_mutex held.
  * Returns negative error code on failure. Zero on success.
  */
-int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
+static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
 {
        struct drm_master *old_master;
        int ret;
@@ -226,6 +226,23 @@ out_unlock:
        return ret;
 }
 
+int drm_master_open(struct drm_file *file_priv)
+{
+       struct drm_device *dev = file_priv->minor->dev;
+       int ret = 0;
+
+       /* 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)
+               ret = drm_new_set_master(dev, file_priv);
+       else
+               file_priv->master = drm_master_get(file_priv->minor->master);
+       mutex_unlock(&dev->master_mutex);
+
+       return ret;
+}
+
 struct drm_master *drm_master_get(struct drm_master *master)
 {
        kref_get(&master->refcount);
index 50b3de990aee08a4094900db33a88f4dfe50f338..e2522672719a412eaf9181f311fed9be933364bf 100644 (file)
@@ -229,19 +229,11 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
                        goto out_prime_destroy;
        }
 
-       /* 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 (drm_is_primary_client(priv) && !priv->minor->master) {
-               /* create a new master */
-               ret = drm_new_set_master(dev, priv);
+       if (drm_is_primary_client(priv)) {
+               ret = drm_master_open(priv);
                if (ret)
                        goto out_close;
-       } else if (drm_is_primary_client(priv)) {
-               /* get a reference to the master */
-               priv->master = drm_master_get(priv->minor->master);
        }
-       mutex_unlock(&dev->master_mutex);
 
        mutex_lock(&dev->filelist_mutex);
        list_add(&priv->lhead, &dev->filelist);
@@ -270,7 +262,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
        return 0;
 
 out_close:
-       mutex_unlock(&dev->master_mutex);
        if (dev->driver->postclose)
                dev->driver->postclose(dev, priv);
 out_prime_destroy:
index d29d426f633fda89b49a03fd520abf87b37f318e..2b9a94f679eda0a618ca657de6995f30a41f8802 100644 (file)
@@ -66,7 +66,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file_priv);
 int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
                         struct drm_file *file_priv);
-int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv);
+int drm_master_open(struct drm_file *file_priv);
 
 /* drm_sysfs.c */
 extern struct class *drm_class;