From patchwork Mon Oct 21 22:33:25 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 3080301 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 E38D3BF924 for ; Mon, 21 Oct 2013 23:25:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1563C20373 for ; Mon, 21 Oct 2013 23:25:43 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 37A2620353 for ; Mon, 21 Oct 2013 23:25:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 22FBBE6FD7 for ; Mon, 21 Oct 2013 16:25:42 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-ea0-f182.google.com (mail-ea0-f182.google.com [209.85.215.182]) by gabe.freedesktop.org (Postfix) with ESMTP id 5D58AE6C39 for ; Mon, 21 Oct 2013 15:33:56 -0700 (PDT) Received: by mail-ea0-f182.google.com with SMTP id o10so3780279eaj.41 for ; Mon, 21 Oct 2013 15:33:55 -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=PewOZLY0y/2hExE4q5w32KI9qqz2/Hi+XhsKZpuuPDM=; b=A4g/Kyp9EOVzUY6rMpASA8L73DT1GBI0jLLSDGvyVLBAQ6ORwwgfpXVNm/Eg23M/zL CJZg8bBLCA5EJyi5eeCEACr90JRETlcKEqKenSHbJJBWa1FUPZ+/TI0VXCdmqqayBWND Km0f0uLlJFeUdzOoBqrY4mhGj7iqtLRn2n5nL3/fD/Kiz263uFwsZr4m3q6h6VmtJaZ8 zEyCIP4DgpSp4J8PxG5EtCxUqzsMaxkZTO1SpqYU1p1TjPPUYNRNj/NpLq7DuyCBQSkp FYuRb9P2xx+uVRwRmIPC/a8IXQIgIdXgmbXA/rBsTAnzX8KDVqh8VDidkN1LXl36UIF8 yYNA== X-Received: by 10.14.95.137 with SMTP id p9mr4573005eef.73.1382394835630; Mon, 21 Oct 2013 15:33:55 -0700 (PDT) Received: from localhost.localdomain (stgt-5f718b64.pool.mediaWays.net. [95.113.139.100]) by mx.google.com with ESMTPSA id e13sm48972229eeu.4.2013.10.21.15.33.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Oct 2013 15:33:54 -0700 (PDT) From: David Herrmann To: dri-devel@lists.freedesktop.org Subject: [RFC v2 3/6] drm: split drm_release() Date: Tue, 22 Oct 2013 00:33:25 +0200 Message-Id: <1382394808-20611-4-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 1.8.4.1 In-Reply-To: <1382394808-20611-1-git-send-email-dh.herrmann@gmail.com> References: <1382394808-20611-1-git-send-email-dh.herrmann@gmail.com> Cc: linux-kernel@vger.kernel.org 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+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-4.5 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 This splits off real file-destruction into drm_close(). drm_release() now calls drm_close() and then takes care of any device-cleanup which isn't strictly related to file-destruction. Besides making the code more readable, this is needed if we want to close open-files during GPU unplug. We could simply fake a drm_close() on each open-file now to logically close them. Signed-off-by: David Herrmann --- drivers/gpu/drm/drm_fops.c | 65 +++++++++++++++++++++++++++------------------- include/drm/drmP.h | 1 + 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index d0e2766..ecdd647 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -450,34 +450,26 @@ int drm_lastclose(struct drm_device * dev) } /** - * Release file. + * drm_close - Close open DRM file + * @file_priv: Open DRM-file to close * - * \param inode device inode - * \param file_priv DRM file private. - * \return zero on success or a negative number on failure. + * This does the real work of drm_release(). All allocated data is freed and + * locks are released. drm_global_mutex must be locked by the caller. The + * drm_file object is not freed and @file_priv->minor->dev stays valid. * - * If the hardware lock is held then free it, and take it again for the kernel - * context since it's necessary to reclaim buffers. Unlink the file private - * data from its list and free it. Decreases the open count and if it reaches - * zero calls drm_lastclose(). + * This does not call drm_lastclose() or any device-cleanup helpers. It's the + * callers responsibility to do this. Drivers must not call this directly. Use + * drm_release() instead. */ -int drm_release(struct inode *inode, struct file *filp) +void drm_close(struct drm_file *file_priv) { - struct drm_file *file_priv = filp->private_data; struct drm_device *dev = file_priv->minor->dev; - int retcode = 0; - - mutex_lock(&drm_global_mutex); DRM_DEBUG("open_count = %d\n", dev->open_count); if (dev->driver->preclose) dev->driver->preclose(dev, file_priv); - /* ======================================================== - * Begin inline drm_release - */ - DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", task_pid_nr(current), (long)old_encode_dev(file_priv->minor->device), @@ -490,7 +482,7 @@ int drm_release(struct inode *inode, struct file *filp) /* if the master has gone away we can't do anything with the lock */ if (file_priv->minor->master) - drm_master_release(dev, filp); + drm_master_release(dev, file_priv->filp); if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) drm_core_reclaim_buffers(dev, file_priv); @@ -573,25 +565,44 @@ int drm_release(struct inode *inode, struct file *filp) drm_prime_destroy_file_private(&file_priv->prime); put_pid(file_priv->pid); - kfree(file_priv); +} - /* ======================================================== - * End inline drm_release - */ +/** + * drm_release - Release open DRM file + * @inode: device inode + * @file_priv: DRM file + * + * Release an open DRM file. This is the default callback for DRM fops. + * We free all internally allocated data, release held locks and unlink the + * open-file from the DRM device. If this is the last user of the unplugged + * device, we also release the device. + * + * RETURNS: + * Returns always zero. + */ +int drm_release(struct inode *inode, struct file *filp) +{ + struct drm_file *file_priv = filp->private_data; + struct drm_device *dev = file_priv->minor->dev; + + mutex_lock(&drm_global_mutex); + + drm_close(file_priv); + kfree(file_priv); if (!--dev->open_count) { - if (atomic_read(&dev->ioctl_count)) { + if (atomic_read(&dev->ioctl_count)) DRM_ERROR("Device busy: %d\n", atomic_read(&dev->ioctl_count)); - retcode = -EBUSY; - } else - retcode = drm_lastclose(dev); + else + drm_lastclose(dev); if (drm_device_is_unplugged(dev)) drm_put_dev(dev); } + mutex_unlock(&drm_global_mutex); - return retcode; + return 0; } EXPORT_SYMBOL(drm_release); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 19b8082..16ff7c4 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1268,6 +1268,7 @@ extern int drm_open(struct inode *inode, struct file *filp); extern int drm_stub_open(struct inode *inode, struct file *filp); extern ssize_t drm_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset); +extern void drm_close(struct drm_file *file_priv); extern int drm_release(struct inode *inode, struct file *filp); /* Mapping support (drm_vm.h) */