From patchwork Wed Aug 9 17:23:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sinclair Yeh X-Patchwork-Id: 9891377 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4EEFD601EB for ; Wed, 9 Aug 2017 17:23:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 364E428AA8 for ; Wed, 9 Aug 2017 17:23:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2AEE728AAB; Wed, 9 Aug 2017 17:23:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AB18628AA8 for ; Wed, 9 Aug 2017 17:23:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EF1126E38C; Wed, 9 Aug 2017 17:23:31 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from EX13-EDG-OU-001.vmware.com (ex13-edg-ou-001.vmware.com [208.91.0.189]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2632D6E386 for ; Wed, 9 Aug 2017 17:23:31 +0000 (UTC) Received: from sc9-mailhost3.vmware.com (10.113.161.73) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Wed, 9 Aug 2017 10:22:38 -0700 Received: from vmware.com (promb-2n-dhcp29.eng.vmware.com [10.20.88.29]) by sc9-mailhost3.vmware.com (Postfix) with SMTP id A1195402BB; Wed, 9 Aug 2017 10:23:13 -0700 (PDT) Received: by vmware.com (sSMTP sendmail emulation); Wed, 09 Aug 2017 19:23:16 +0200 From: Sinclair Yeh To: Subject: [PATCH 7/9] drm/vmwgfx: Add export fence to file descriptor support Date: Wed, 9 Aug 2017 19:23:02 +0200 Message-ID: <1502299384-63140-8-git-send-email-syeh@vmware.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1502299384-63140-1-git-send-email-syeh@vmware.com> References: <1502299384-63140-1-git-send-email-syeh@vmware.com> MIME-Version: 1.0 Received-SPF: None (EX13-EDG-OU-001.vmware.com: syeh@vmware.com does not designate permitted sender hosts) X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Added code to link a fence to a out_fence_fd file descriptor and thread out_fence_fd down to vmw_execbuf_copy_fence_user() so it can be copied into the IOCTL reply and be passed back up the the user. v2: Make sure to sync and clean up in case of failure Signed-off-by: Sinclair Yeh Reviewed-by: Deepak Singh Rawat Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 8 +++- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 69 +++++++++++++++++++++++++++++---- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index c4dc3fa..5269be4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -40,6 +40,7 @@ #include #include #include "vmwgfx_fence.h" +#include #define VMWGFX_DRIVER_DATE "20170607" #define VMWGFX_DRIVER_MAJOR 2 @@ -825,7 +826,8 @@ extern int vmw_execbuf_process(struct drm_file *file_priv, uint32_t dx_context_handle, struct drm_vmw_fence_rep __user *user_fence_rep, - struct vmw_fence_obj **out_fence); + struct vmw_fence_obj **out_fence, + uint32_t flags); extern void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, struct vmw_fence_obj *fence); extern void vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv); @@ -840,7 +842,9 @@ extern void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, struct drm_vmw_fence_rep __user *user_fence_rep, struct vmw_fence_obj *fence, - uint32_t fence_handle); + uint32_t fence_handle, + int32_t out_fence_fd, + struct sync_file *sync_file); extern int vmw_validate_single_buffer(struct vmw_private *dev_priv, struct ttm_buffer_object *bo, bool interruptible, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index e9cdaa4..3cd48d1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -3830,6 +3830,8 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv, * which the information should be copied. * @fence: Pointer to the fenc object. * @fence_handle: User-space fence handle. + * @out_fence_fd: exported file descriptor for the fence. -1 if not used + * @sync_file: Only used to clean up in case of an error in this function. * * This function copies fence information to user-space. If copying fails, * The user-space struct drm_vmw_fence_rep::error member is hopefully @@ -3845,7 +3847,9 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, int ret, struct drm_vmw_fence_rep __user *user_fence_rep, struct vmw_fence_obj *fence, - uint32_t fence_handle) + uint32_t fence_handle, + int32_t out_fence_fd, + struct sync_file *sync_file) { struct drm_vmw_fence_rep fence_rep; @@ -3855,6 +3859,7 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, memset(&fence_rep, 0, sizeof(fence_rep)); fence_rep.error = ret; + fence_rep.fd = out_fence_fd; if (ret == 0) { BUG_ON(fence == NULL); @@ -3877,6 +3882,14 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, * and unreference the handle. */ if (unlikely(ret != 0) && (fence_rep.error == 0)) { + if (sync_file) + fput(sync_file->file); + + if (fence_rep.fd != -1) { + put_unused_fd(fence_rep.fd); + fence_rep.fd = -1; + } + ttm_ref_object_base_unref(vmw_fp->tfile, fence_handle, TTM_REF_USAGE); DRM_ERROR("Fence copy error. Syncing.\n"); @@ -4052,7 +4065,8 @@ int vmw_execbuf_process(struct drm_file *file_priv, uint64_t throttle_us, uint32_t dx_context_handle, struct drm_vmw_fence_rep __user *user_fence_rep, - struct vmw_fence_obj **out_fence) + struct vmw_fence_obj **out_fence, + uint32_t flags) { struct vmw_sw_context *sw_context = &dev_priv->ctx; struct vmw_fence_obj *fence = NULL; @@ -4062,20 +4076,33 @@ int vmw_execbuf_process(struct drm_file *file_priv, struct ww_acquire_ctx ticket; uint32_t handle; int ret; + int32_t out_fence_fd = -1; + struct sync_file *sync_file = NULL; + + + if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) { + out_fence_fd = get_unused_fd_flags(O_CLOEXEC); + if (out_fence_fd < 0) { + DRM_ERROR("Failed to get a fence file descriptor.\n"); + return out_fence_fd; + } + } if (throttle_us) { ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.marker_queue, throttle_us); if (ret) - return ret; + goto out_free_fence_fd; } kernel_commands = vmw_execbuf_cmdbuf(dev_priv, user_commands, kernel_commands, command_size, &header); - if (IS_ERR(kernel_commands)) - return PTR_ERR(kernel_commands); + if (IS_ERR(kernel_commands)) { + ret = PTR_ERR(kernel_commands); + goto out_free_fence_fd; + } ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex); if (ret) { @@ -4211,8 +4238,32 @@ int vmw_execbuf_process(struct drm_file *file_priv, __vmw_execbuf_release_pinned_bo(dev_priv, fence); vmw_clear_validations(sw_context); + + /* + * If anything fails here, give up trying to export the fence + * and do a sync since the user mode will not be able to sync + * the fence itself. This ensures we are still functionally + * correct. + */ + if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) { + + sync_file = sync_file_create(&fence->base); + if (!sync_file) { + DRM_ERROR("Unable to create sync file for fence\n"); + put_unused_fd(out_fence_fd); + out_fence_fd = -1; + + (void) vmw_fence_obj_wait(fence, false, false, + VMW_FENCE_WAIT_TIMEOUT); + } else { + /* Link the fence with the FD created earlier */ + fd_install(out_fence_fd, sync_file->file); + } + } + vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, - user_fence_rep, fence, handle); + user_fence_rep, fence, handle, + out_fence_fd, sync_file); /* Don't unreference when handing fence out */ if (unlikely(out_fence != NULL)) { @@ -4263,6 +4314,9 @@ int vmw_execbuf_process(struct drm_file *file_priv, out_free_header: if (header) vmw_cmdbuf_header_free(header); +out_free_fence_fd: + if (out_fence_fd >= 0) + put_unused_fd(out_fence_fd); return ret; } @@ -4479,7 +4533,8 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, NULL, arg.command_size, arg.throttle_us, arg.context_handle, (void __user *)(unsigned long)arg.fence_rep, - NULL); + NULL, + arg.flags); ttm_read_unlock(&dev_priv->reservation_sem); if (unlikely(ret != 0)) goto out; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index e62f027..4210e18 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -1149,7 +1149,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, } vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence, - handle); + handle, -1, NULL); vmw_fence_obj_unreference(&fence); return 0; out_no_create: diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 620180d..2ff8c12 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -2485,7 +2485,7 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv, if (file_priv) vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, user_fence_rep, fence, - handle); + handle, -1, NULL); if (out_fence) *out_fence = fence; else