From patchwork Wed Jan 29 14:01:54 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 3551181 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C145C9F381 for ; Wed, 29 Jan 2014 14:02:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8D9AE20170 for ; Wed, 29 Jan 2014 14:02:46 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 429472018A for ; Wed, 29 Jan 2014 14:02:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AF127436F9; Wed, 29 Jan 2014 06:02:37 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-ee0-f42.google.com (mail-ee0-f42.google.com [74.125.83.42]) by gabe.freedesktop.org (Postfix) with ESMTP id 8F720436F0 for ; Wed, 29 Jan 2014 06:02:28 -0800 (PST) Received: by mail-ee0-f42.google.com with SMTP id e49so925381eek.29 for ; Wed, 29 Jan 2014 06:02:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=C7vWVtWC9iMmPnZfxxgOiqaRjXgKQ80gKeUIoLcjHts=; b=R7KCevKg2anxkgM8B94PBAYPKNBlM7waJAxQlK258QMCUsIWsi7JbJ3ZqX8hYRjXvr eRX1QYOzJxHXvX9uVx+9iBJOd4nwiCccRYv0W+G849AyH8t7K4oflfMGEfx4NAXNwwvh If9CzovYYxfjBXRZQa3yAGmDMmVaYBfqZAxpm2W47v5M27AviRCpN0rdH5CoIpq1IESy qFwRczxm86ySeg8BhFNSjIjF82A1sbI2BnbWI57kz27CjF8jW7RLP0jiZXg+YMMSeoLb XBNmpoFrVyao2JnNsbbX1mzkaR9/TpoTMhecCQIlMvrpY9Bpn9HG/tMAhmACHE+VbVpl SWhQ== X-Received: by 10.14.210.130 with SMTP id u2mr480846eeo.108.1391004147670; Wed, 29 Jan 2014 06:02:27 -0800 (PST) Received: from david-ub.localdomain (stgt-5f71657e.pool.mediaWays.net. [95.113.101.126]) by mx.google.com with ESMTPSA id o13sm9094881eex.19.2014.01.29.06.02.26 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 29 Jan 2014 06:02:26 -0800 (PST) From: David Herrmann To: dri-devel@lists.freedesktop.org Subject: [PATCH 07/13] drm: allocate minors early Date: Wed, 29 Jan 2014 15:01:54 +0100 Message-Id: <1391004120-687-8-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1391004120-687-1-git-send-email-dh.herrmann@gmail.com> References: <1391004120-687-1-git-send-email-dh.herrmann@gmail.com> Cc: Daniel Vetter X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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;