From patchwork Wed Jul 23 15:26:38 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 4611681 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 703F1C0514 for ; Wed, 23 Jul 2014 15:30:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 832652017D for ; Wed, 23 Jul 2014 15:30:42 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 750B620107 for ; Wed, 23 Jul 2014 15:30:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2E83E6E65C; Wed, 23 Jul 2014 08:30:40 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wi0-f178.google.com (mail-wi0-f178.google.com [209.85.212.178]) by gabe.freedesktop.org (Postfix) with ESMTP id B5E216E65C for ; Wed, 23 Jul 2014 08:30:38 -0700 (PDT) Received: by mail-wi0-f178.google.com with SMTP id hi2so2444426wib.17 for ; Wed, 23 Jul 2014 08:30:37 -0700 (PDT) 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=RiTfnyiivLzdMvOwks5i5xy6sGlmwZwumkj8oC6jy+Y=; b=t9CpdEPG0n0cfrvxcpjtT4QgiYqLnxoSIPYr6YkakzES4IsG3mkcwLnJjWv6FCbMV1 VWq2FXL68LNq7cg4XgEuxNJ3eA3AB1zy20BKuxqK5Ml7IePjXdsaCRsl47IscUlqVgzY tDzFmtoVPGgdkoHyqDorIndpOkHA2wilCtdAOqGnBzXYRYuAiMy0XzmnUQXt+YwVb7xr u1a/zGukqqLsdzSULSCdgB9HyEBpmX6syaUlC6MmT1zw6GCp3H9FgKSNTa7r5boubxar DcY1YXeFYzs6gxirfqjHMp5NvtnpGUgrEiIjgXJ//1eii+/s9AkEAetAbhnmnBlyEfAB Tc7A== X-Received: by 10.180.94.166 with SMTP id dd6mr4013608wib.33.1406129437659; Wed, 23 Jul 2014 08:30:37 -0700 (PDT) Received: from david-tp.localdomain (stgt-5f71b1a8.pool.mediaWays.net. [95.113.177.168]) by mx.google.com with ESMTPSA id bx2sm7092580wjb.47.2014.07.23.08.30.35 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 23 Jul 2014 08:30:36 -0700 (PDT) From: David Herrmann To: dri-devel@lists.freedesktop.org Subject: [PATCH 03/12] drm: call ->firstopen() before ->open() Date: Wed, 23 Jul 2014 17:26:38 +0200 Message-Id: <1406129207-1302-4-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 2.0.2 In-Reply-To: <1406129207-1302-1-git-send-email-dh.herrmann@gmail.com> References: <1406129207-1302-1-git-send-email-dh.herrmann@gmail.com> Cc: Daniel Vetter X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.1 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 Lets order things correctly: ->load() ->fistopen() ->open() ->close() ->lastclose() ->unload() This doesn't change much as only savage and radeon use ->firstopen() and they just do map-initialization. Therefore, the global drm mutex makes sure there cannot be any other f_op between ->open() and ->firstopen(). However, once we get rid of that lock, we really want ->firstopen() to initialize the device before ->open() is called. Furthermore, this fixes the clean-up path in drm_open(). We currently don't cleanup the drm_file object if ->firstopen() fails. Signed-off-by: David Herrmann --- drivers/gpu/drm/drm_fops.c | 139 +++++++++++++++++++++------------------------ include/drm/drmP.h | 2 +- 2 files changed, 66 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 021fe5d..8e73519 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -45,7 +45,7 @@ EXPORT_SYMBOL(drm_global_mutex); static int drm_open_helper(struct file *filp, struct drm_minor *minor); -static int drm_setup(struct drm_device * dev) +static int drm_firstopen(struct drm_device * dev) { int ret; @@ -66,6 +66,57 @@ static int drm_setup(struct drm_device * dev) } /** + * drm_legacy_dev_reinit + * + * Reinitializes a legacy/ums drm device in it's lastclose function. + */ +static void drm_legacy_dev_reinit(struct drm_device *dev) +{ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return; + + dev->sigdata.lock = NULL; + + dev->context_flag = 0; + dev->last_context = 0; + dev->if_version = 0; +} + +void drm_lastclose(struct drm_device * dev) +{ + struct drm_vma_entry *vma, *vma_temp; + + DRM_DEBUG("\n"); + + if (dev->driver->lastclose) + dev->driver->lastclose(dev); + DRM_DEBUG("driver lastclose completed\n"); + + if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET)) + drm_irq_uninstall(dev); + + mutex_lock(&dev->struct_mutex); + + drm_agp_clear(dev); + + drm_legacy_sg_cleanup(dev); + + /* Clear vma list (only built for debugging) */ + list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) { + list_del(&vma->head); + kfree(vma); + } + + drm_legacy_dma_takedown(dev); + + mutex_unlock(&dev->struct_mutex); + + drm_legacy_dev_reinit(dev); + + DRM_DEBUG("lastclose completed\n"); +} + +/** * Open file. * * \param inode device inode @@ -81,31 +132,33 @@ int drm_open(struct inode *inode, struct file *filp) struct drm_device *dev; struct drm_minor *minor; int retcode; - int need_setup = 0; minor = drm_minor_acquire(iminor(inode)); if (IS_ERR(minor)) return PTR_ERR(minor); dev = minor->dev; - if (!dev->open_count++) - need_setup = 1; /* share address_space across all char-devs of a single device */ filp->f_mapping = dev->anon_inode->i_mapping; + if (!dev->open_count) { + retcode = drm_firstopen(dev); + if (retcode) + goto err_minor; + } + ++dev->open_count; + retcode = drm_open_helper(filp, minor); if (retcode) goto err_undo; - if (need_setup) { - retcode = drm_setup(dev); - if (retcode) - goto err_undo; - } + return 0; err_undo: - dev->open_count--; + if (!--dev->open_count) + drm_lastclose(dev); +err_minor: drm_minor_release(minor); return retcode; } @@ -346,67 +399,6 @@ static void drm_events_release(struct drm_file *file_priv) } /** - * drm_legacy_dev_reinit - * - * Reinitializes a legacy/ums drm device in it's lastclose function. - */ -static void drm_legacy_dev_reinit(struct drm_device *dev) -{ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - dev->sigdata.lock = NULL; - - dev->context_flag = 0; - dev->last_context = 0; - dev->if_version = 0; -} - -/** - * Take down the DRM device. - * - * \param dev DRM device structure. - * - * Frees every resource in \p dev. - * - * \sa drm_device - */ -int drm_lastclose(struct drm_device * dev) -{ - struct drm_vma_entry *vma, *vma_temp; - - DRM_DEBUG("\n"); - - if (dev->driver->lastclose) - dev->driver->lastclose(dev); - DRM_DEBUG("driver lastclose completed\n"); - - if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET)) - drm_irq_uninstall(dev); - - mutex_lock(&dev->struct_mutex); - - drm_agp_clear(dev); - - drm_legacy_sg_cleanup(dev); - - /* Clear vma list (only built for debugging) */ - list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) { - list_del(&vma->head); - kfree(vma); - } - - drm_legacy_dma_takedown(dev); - - mutex_unlock(&dev->struct_mutex); - - drm_legacy_dev_reinit(dev); - - DRM_DEBUG("lastclose completed\n"); - return 0; -} - -/** * Release file. * * \param inode device inode @@ -423,7 +415,6 @@ int drm_release(struct inode *inode, struct file *filp) struct drm_file *file_priv = filp->private_data; struct drm_minor *minor = file_priv->minor; struct drm_device *dev = minor->dev; - int retcode = 0; mutex_lock(&drm_global_mutex); @@ -541,7 +532,7 @@ int drm_release(struct inode *inode, struct file *filp) */ if (!--dev->open_count) { - retcode = drm_lastclose(dev); + drm_lastclose(dev); if (drm_device_is_unplugged(dev)) drm_put_dev(dev); } @@ -549,7 +540,7 @@ int drm_release(struct inode *inode, struct file *filp) drm_minor_release(minor); - return retcode; + return 0; } EXPORT_SYMBOL(drm_release); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d3d9be6..d1730c5 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1181,7 +1181,7 @@ extern long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); extern long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_lastclose(struct drm_device *dev); +extern void drm_lastclose(struct drm_device *dev); extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags); /* Device support (drm_fops.h) */