dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: David Herrmann <dh.herrmann@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Subject: [PATCH 07/13] drm: allocate minors early
Date: Wed, 29 Jan 2014 15:01:54 +0100	[thread overview]
Message-ID: <1391004120-687-8-git-send-email-dh.herrmann@gmail.com> (raw)
In-Reply-To: <1391004120-687-1-git-send-email-dh.herrmann@gmail.com>

Instead of waiting for device-registration, we now allocate minor-objects
during device allocation. The minors are not registered or assigned an ID.
This is still postponed to device-registration.

While at it, remove the superfluous output-parameter in drm_get_minor().

The reason for this early allocation is to make
dev->primary/control/render available atomically. So once the device is
alive, all of them are already set and we never have the situation where
one of them is set after another (they're either NULL or set, but never
changed). This will eventually allow us to reduce minor-ID allocation to
one base-ID instead of a single ID for each.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
 drivers/gpu/drm/drm_stub.c | 110 +++++++++++++++++++++++++++++----------------
 1 file changed, 71 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index d3232b6..9c2da5f 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -260,21 +260,49 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 	return 0;
 }
 
+static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
+					     unsigned int type)
+{
+	switch (type) {
+	case DRM_MINOR_LEGACY:
+		return &dev->primary;
+	case DRM_MINOR_RENDER:
+		return &dev->render;
+	case DRM_MINOR_CONTROL:
+		return &dev->control;
+	default:
+		return NULL;
+	}
+}
+
+static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
+{
+	struct drm_minor *minor;
+
+	minor = kzalloc(sizeof(*minor), GFP_KERNEL);
+	if (!minor)
+		return -ENOMEM;
+
+	minor->type = type;
+	minor->dev = dev;
+	INIT_LIST_HEAD(&minor->master_list);
+
+	*drm_minor_get_slot(dev, type) = minor;
+	return 0;
+}
+
 /**
- * drm_get_minor - Allocate and register new DRM minor
+ * drm_get_minor - Register DRM minor
  * @dev: DRM device
- * @minor: Pointer to where new minor is stored
  * @type: Type of minor
  *
- * Allocate a new minor of the given type and register it. A pointer to the new
- * minor is returned in @minor.
+ * Register minor of given type.
  * Caller must hold the global DRM mutex.
  *
  * RETURNS:
  * 0 on success, negative error code on failure.
  */
-static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor,
-			 int type)
+static int drm_get_minor(struct drm_device *dev, unsigned int type)
 {
 	struct drm_minor *new_minor;
 	int ret;
@@ -282,21 +310,16 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor,
 
 	DRM_DEBUG("\n");
 
+	new_minor = *drm_minor_get_slot(dev, type);
+	if (!new_minor)
+		return 0;
+
 	minor_id = drm_minor_get_id(dev, type);
 	if (minor_id < 0)
 		return minor_id;
 
-	new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL);
-	if (!new_minor) {
-		ret = -ENOMEM;
-		goto err_idr;
-	}
-
-	new_minor->type = type;
 	new_minor->device = MKDEV(DRM_MAJOR, minor_id);
-	new_minor->dev = dev;
 	new_minor->index = minor_id;
-	INIT_LIST_HEAD(&new_minor->master_list);
 
 	idr_replace(&drm_minors_idr, new_minor, minor_id);
 
@@ -314,7 +337,6 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor,
 		       "DRM: Error sysfs_device_add.\n");
 		goto err_debugfs;
 	}
-	*minor = new_minor;
 
 	DRM_DEBUG("new minor assigned %d\n", minor_id);
 	return 0;
@@ -325,10 +347,7 @@ err_debugfs:
 	drm_debugfs_cleanup(new_minor);
 err_mem:
 #endif
-	kfree(new_minor);
-err_idr:
 	idr_remove(&drm_minors_idr, minor_id);
-	*minor = NULL;
 	return ret;
 }
 
@@ -495,8 +514,24 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
 	mutex_init(&dev->struct_mutex);
 	mutex_init(&dev->ctxlist_mutex);
 
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL);
+		if (ret)
+			goto err_minors;
+	}
+
+	if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
+		ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
+		if (ret)
+			goto err_minors;
+	}
+
+	ret = drm_minor_alloc(dev, DRM_MINOR_LEGACY);
+	if (ret)
+		goto err_minors;
+
 	if (drm_ht_create(&dev->map_hash, 12))
-		goto err_free;
+		goto err_minors;
 
 	ret = drm_ctxbitmap_init(dev);
 	if (ret) {
@@ -518,7 +553,10 @@ err_ctxbitmap:
 	drm_ctxbitmap_cleanup(dev);
 err_ht:
 	drm_ht_remove(&dev->map_hash);
-err_free:
+err_minors:
+	drm_put_minor(dev->control);
+	drm_put_minor(dev->render);
+	drm_put_minor(dev->primary);
 	kfree(dev);
 	return NULL;
 }
@@ -605,26 +643,22 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
 
 	mutex_lock(&drm_global_mutex);
 
-	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-		ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
-		if (ret)
-			goto out_unlock;
-	}
+	ret = drm_get_minor(dev, DRM_MINOR_CONTROL);
+	if (ret)
+		goto err_minors;
 
-	if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
-		ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
-		if (ret)
-			goto err_control_node;
-	}
+	ret = drm_get_minor(dev, DRM_MINOR_RENDER);
+	if (ret)
+		goto err_minors;
 
-	ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
+	ret = drm_get_minor(dev, DRM_MINOR_LEGACY);
 	if (ret)
-		goto err_render_node;
+		goto err_minors;
 
 	if (dev->driver->load) {
 		ret = dev->driver->load(dev, flags);
 		if (ret)
-			goto err_primary_node;
+			goto err_minors;
 	}
 
 	/* setup grouping for legacy outputs */
@@ -641,12 +675,10 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
 err_unload:
 	if (dev->driver->unload)
 		dev->driver->unload(dev);
-err_primary_node:
-	drm_unplug_minor(dev->primary);
-err_render_node:
-	drm_unplug_minor(dev->render);
-err_control_node:
+err_minors:
 	drm_unplug_minor(dev->control);
+	drm_unplug_minor(dev->render);
+	drm_unplug_minor(dev->primary);
 out_unlock:
 	mutex_unlock(&drm_global_mutex);
 	return ret;
-- 
1.8.5.3

  parent reply	other threads:[~2014-01-29 14:02 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-29 14:01 [PATCH 00/13] DRM Reliable Minor-IDs David Herrmann
2014-01-29 14:01 ` [PATCH 01/13] drm: group dev-lifetime related members David Herrmann
2014-01-29 14:01 ` [PATCH 02/13] drm: skip redundant minor-lookup in open path David Herrmann
2014-01-29 14:01 ` [PATCH 03/13] drm: remove unused DRM_MINOR_UNASSIGNED David Herrmann
2014-01-29 14:01 ` [PATCH 04/13] drm: turn DRM_MINOR_* into enum David Herrmann
2014-01-29 14:01 ` [PATCH 05/13] drm: provide device-refcount David Herrmann
2014-02-12 13:25   ` Daniel Vetter
2014-02-12 14:44     ` David Herrmann
2014-02-12 16:26       ` Daniel Vetter
2014-02-12 16:40         ` Greg KH
2014-02-12 17:48           ` David Herrmann
2014-02-12 18:31             ` Daniel Vetter
2014-02-12 18:38             ` Greg KH
2014-02-21  7:01   ` Thierry Reding
2014-02-24 13:51     ` David Herrmann
2014-01-29 14:01 ` [PATCH 06/13] drm: add minor-lookup/release helpers David Herrmann
2014-02-21  7:09   ` Thierry Reding
2014-02-21  7:34     ` David Herrmann
2014-02-21  7:37       ` Thierry Reding
2014-01-29 14:01 ` David Herrmann [this message]
2014-01-29 14:01 ` [PATCH 08/13] drm: move drm_put_minor() to drm_minor_free() David Herrmann
2014-01-29 14:01 ` [PATCH 09/13] drm: rename drm_unplug/get_minor() to drm_minor_register/unregister() David Herrmann
2014-02-21  7:21   ` Thierry Reding
2014-02-24 13:52     ` David Herrmann
2014-01-29 14:01 ` [PATCH 10/13] drm: remove unneeded #ifdef CONFIG_DEBUGFS David Herrmann
2014-01-29 14:01 ` [PATCH 11/13] drm: remove redundant minor->device field David Herrmann
2014-02-12 13:36   ` Daniel Vetter
2014-02-21  7:30     ` Thierry Reding
2014-02-21 20:07       ` David Herrmann
2014-01-29 14:01 ` [PATCH 12/13] drm: make minor-IDs reliable David Herrmann
2014-01-29 14:02 ` [PATCH 13/13] drm: remove redundant minor->index David Herrmann
2014-02-21  7:30 ` [PATCH 00/13] DRM Reliable Minor-IDs Thierry Reding

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=1391004120-687-8-git-send-email-dh.herrmann@gmail.com \
    --to=dh.herrmann@gmail.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    /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