From patchwork Thu Dec 20 00:27:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Airlie X-Patchwork-Id: 1897611 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 7896DDF230 for ; Thu, 20 Dec 2012 00:36:29 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 37A05E662D for ; Wed, 19 Dec 2012 16:36:29 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTP id 1CBCDE6643 for ; Wed, 19 Dec 2012 16:27:51 -0800 (PST) Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qBK0RoJm004799 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 19 Dec 2012 19:27:50 -0500 Received: from prime.bne.redhat.com (dhcp-40-183.bne.redhat.com [10.64.40.183]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qBK0RnF8018971 for ; Wed, 19 Dec 2012 19:27:49 -0500 From: Dave Airlie To: dri-devel@lists.freedesktop.org Subject: [PATCH] drm/prime: keep a reference from the handle to exported dma-buf Date: Thu, 20 Dec 2012 10:27:48 +1000 Message-Id: <1355963268-21310-1-git-send-email-airlied@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 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 From: Dave Airlie This is likely the simplest solution to the problem, and seems to work fine. When we export a dma_buf from a gem object, we keep track of it with the handle, we take a reference to the dma_buf. When we close the handle (i.e. userspace is finished with the buffer), we drop the reference to the dma_buf, and it gets collected. I'd like to refrain from too much in this patch as I'd like it to go to stable, so future cleanups should look at maybe reducing the obj storing two pointers etc. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_gem.c | 2 +- drivers/gpu/drm/drm_prime.c | 34 ++++++++++++++++++++++++++++++---- include/drm/drmP.h | 1 + 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 24efae4..e221b7b 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -209,7 +209,7 @@ drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) obj->import_attach->dmabuf); } if (obj->export_dma_buf) { - drm_prime_remove_imported_buf_handle(&filp->prime, + drm_prime_remove_exported_buf_handle(&filp->prime, obj->export_dma_buf); } } diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 7f12573..583d126 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -62,6 +62,8 @@ struct drm_prime_member { uint32_t handle; }; +static int drm_prime_add_exported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle); + int drm_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd) @@ -104,8 +106,8 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, /* if we've exported this buffer the cheat and add it to the import list * so we get the correct handle back */ - ret = drm_prime_add_imported_buf_handle(&file_priv->prime, - obj->export_dma_buf, handle); + ret = drm_prime_add_exported_buf_handle(&file_priv->prime, + obj->export_dma_buf, handle); if (ret) { drm_gem_object_unreference_unlocked(obj); mutex_unlock(&file_priv->prime.lock); @@ -307,7 +309,7 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) } EXPORT_SYMBOL(drm_prime_destroy_file_private); -int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle) +static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle) { struct drm_prime_member *member; @@ -320,6 +322,18 @@ int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv list_add(&member->entry, &prime_fpriv->head); return 0; } + +int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle) +{ + return drm_prime_add_buf_handle(prime_fpriv, dma_buf, handle); +} + +static int drm_prime_add_exported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle) +{ + /* take a reference to the buf handle for this case */ + get_dma_buf(dma_buf); + return drm_prime_add_buf_handle(prime_fpriv, dma_buf, handle); +} EXPORT_SYMBOL(drm_prime_add_imported_buf_handle); int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle) @@ -336,7 +350,7 @@ int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fp } EXPORT_SYMBOL(drm_prime_lookup_imported_buf_handle); -void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) +static void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) { struct drm_prime_member *member, *safe; @@ -349,4 +363,16 @@ void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_f } mutex_unlock(&prime_fpriv->lock); } + +void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) +{ + drm_prime_remove_buf_handle(prime_fpriv, dma_buf); +} EXPORT_SYMBOL(drm_prime_remove_imported_buf_handle); + +void drm_prime_remove_exported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) +{ + drm_prime_remove_buf_handle(prime_fpriv, dma_buf); + dma_buf_put(dma_buf); +} +EXPORT_SYMBOL(drm_prime_remove_exported_buf_handle); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fad21c9..6dcfa2e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1562,6 +1562,7 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle); int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle); void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf); +void drm_prime_remove_exported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf); int drm_prime_add_dma_buf(struct drm_device *dev, struct drm_gem_object *obj); int drm_prime_lookup_obj(struct drm_device *dev, struct dma_buf *buf,