From patchwork Tue Apr 11 03:22:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dave Airlie X-Patchwork-Id: 9674519 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 2116C600CB for ; Tue, 11 Apr 2017 03:22:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 275BD28469 for ; Tue, 11 Apr 2017 03:22:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1C2ED284CF; Tue, 11 Apr 2017 03:22:31 +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, DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 62CAD28469 for ; Tue, 11 Apr 2017 03:22:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9B6D56E406; Tue, 11 Apr 2017 03:22:28 +0000 (UTC) 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 ESMTPS id D4AAC6E3D4; Tue, 11 Apr 2017 03:22:25 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 288AB8123F; Tue, 11 Apr 2017 03:22:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 288AB8123F Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=airlied@gmail.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 288AB8123F Received: from dreadlord-bne-redhat-com.bne.redhat.com (dhcp-40-179.bne.redhat.com [10.64.40.179]) by smtp.corp.redhat.com (Postfix) with ESMTP id 662BA5C6F3; Tue, 11 Apr 2017 03:22:24 +0000 (UTC) From: Dave Airlie To: amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Subject: [PATCH 1/8] sync_file: add type/flags to sync file object creation. Date: Tue, 11 Apr 2017 13:22:13 +1000 Message-Id: <20170411032220.21101-2-airlied@gmail.com> In-Reply-To: <20170411032220.21101-1-airlied@gmail.com> References: <20170411032220.21101-1-airlied@gmail.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 11 Apr 2017 03:22:25 +0000 (UTC) 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 From: Dave Airlie This allows us to create sync files with different semantics, and clearly define the interoperation between them it also provides flags to allow for tweaks on those semantics. This provides a validation interface for drivers that accept types from userspace so they can return EINVAL instead of ENOMEM. This provides an ioctl for userspace to retrieve the type/flags of an object it may recieve from somewhere else. Reviewed-by: Christian König Signed-off-by: Dave Airlie --- Documentation/driver-api/dma-buf.rst | 6 ++++ drivers/dma-buf/sw_sync.c | 2 +- drivers/dma-buf/sync_file.c | 64 +++++++++++++++++++++++++++++++++--- drivers/gpu/drm/drm_atomic.c | 2 +- include/linux/sync_file.h | 9 ++++- include/uapi/linux/sync_file.h | 27 +++++++++++++++ 6 files changed, 103 insertions(+), 7 deletions(-) diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst index 31671b4..bf2f7d5 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -163,3 +163,9 @@ DMA Fence uABI/Sync File .. kernel-doc:: include/linux/sync_file.h :internal: + +Sync File IOCTL Definitions +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/uapi/linux/sync_file.h + :internal: diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c index 69c5ff3..1c47de6 100644 --- a/drivers/dma-buf/sw_sync.c +++ b/drivers/dma-buf/sw_sync.c @@ -315,7 +315,7 @@ static long sw_sync_ioctl_create_fence(struct sync_timeline *obj, goto err; } - sync_file = sync_file_create(&pt->base); + sync_file = sync_file_create(&pt->base, SYNC_FILE_TYPE_FENCE, 0); dma_fence_put(&pt->base); if (!sync_file) { err = -ENOMEM; diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 2321035..07392af 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -28,9 +28,32 @@ static const struct file_operations sync_file_fops; -static struct sync_file *sync_file_alloc(void) +/** + * sync_file_validate_type_flags - validate type/flags for support + * @type: type of sync file object + * @flags: flags to sync object. + * + * Validates the flags are correct so userspace can get a more + * detailed error type. + */ +int sync_file_validate_type_flags(uint32_t type, uint32_t flags) +{ + if (flags) + return -EINVAL; + if (type != SYNC_FILE_TYPE_FENCE) + return -EINVAL; + return 0; +} +EXPORT_SYMBOL(sync_file_validate_type_flags); + +static struct sync_file *sync_file_alloc(uint32_t type, uint32_t flags) { struct sync_file *sync_file; + int ret; + + ret = sync_file_validate_type_flags(type, flags); + if (ret) + return NULL; sync_file = kzalloc(sizeof(*sync_file), GFP_KERNEL); if (!sync_file) @@ -47,6 +70,8 @@ static struct sync_file *sync_file_alloc(void) INIT_LIST_HEAD(&sync_file->cb.node); + sync_file->type = type; + sync_file->flags = flags; return sync_file; err: @@ -66,17 +91,21 @@ static void fence_check_cb_func(struct dma_fence *f, struct dma_fence_cb *cb) /** * sync_file_create() - creates a sync file * @fence: fence to add to the sync_fence + * @type: type of sync file to create + * @flags: flags to create sync file with. * * Creates a sync_file containg @fence. This function acquires and additional * reference of @fence for the newly-created &sync_file, if it succeeds. The * sync_file can be released with fput(sync_file->file). Returns the * sync_file or NULL in case of error. */ -struct sync_file *sync_file_create(struct dma_fence *fence) +struct sync_file *sync_file_create(struct dma_fence *fence, + uint32_t type, + uint32_t flags) { struct sync_file *sync_file; - sync_file = sync_file_alloc(); + sync_file = sync_file_alloc(type, flags); if (!sync_file) return NULL; @@ -200,7 +229,10 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, struct dma_fence **fences, **nfences, **a_fences, **b_fences; int i, i_a, i_b, num_fences, a_num_fences, b_num_fences; - sync_file = sync_file_alloc(); + if (a->type != b->type) + return NULL; + + sync_file = sync_file_alloc(a->type, a->flags); if (!sync_file) return NULL; @@ -437,6 +469,27 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file, return ret; } +static long sync_file_ioctl_type(struct sync_file *sync_file, + unsigned long arg) +{ + struct sync_file_type type; + int ret; + if (copy_from_user(&type, (void __user *)arg, sizeof(type))) + return -EFAULT; + + if (type.flags || type.type) + return -EINVAL; + + type.type = sync_file->type; + type.flags = sync_file->flags; + + if (copy_to_user((void __user *)arg, &type, sizeof(type))) + ret = -EFAULT; + else + ret = 0; + return ret; +} + static long sync_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -449,6 +502,9 @@ static long sync_file_ioctl(struct file *file, unsigned int cmd, case SYNC_IOC_FILE_INFO: return sync_file_ioctl_fence_info(sync_file, arg); + case SYNC_IOC_TYPE: + return sync_file_ioctl_type(sync_file, arg); + default: return -ENOTTY; } diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a567310..bb5a740 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1917,7 +1917,7 @@ static int setup_out_fence(struct drm_out_fence_state *fence_state, if (put_user(fence_state->fd, fence_state->out_fence_ptr)) return -EFAULT; - fence_state->sync_file = sync_file_create(fence); + fence_state->sync_file = sync_file_create(fence, SYNC_FILE_TYPE_FENCE, 0); if (!fence_state->sync_file) return -ENOMEM; diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h index 3e3ab84..ede4182 100644 --- a/include/linux/sync_file.h +++ b/include/linux/sync_file.h @@ -20,6 +20,8 @@ #include #include #include +#include + /** * struct sync_file - sync file to export to the userspace @@ -30,6 +32,8 @@ * @wq: wait queue for fence signaling * @fence: fence with the fences in the sync_file * @cb: fence callback information + * @type: sync file type + * @flags: flags used to create sync file */ struct sync_file { struct file *file; @@ -43,11 +47,14 @@ struct sync_file { struct dma_fence *fence; struct dma_fence_cb cb; + uint32_t type; + uint32_t flags; }; #define POLL_ENABLED DMA_FENCE_FLAG_USER_BITS -struct sync_file *sync_file_create(struct dma_fence *fence); +int sync_file_validate_type_flags(uint32_t type, uint32_t flags); +struct sync_file *sync_file_create(struct dma_fence *fence, uint32_t type, uint32_t flags); struct dma_fence *sync_file_get_fence(int fd); #endif /* _LINUX_SYNC_H */ diff --git a/include/uapi/linux/sync_file.h b/include/uapi/linux/sync_file.h index 5b287d6..f439cda 100644 --- a/include/uapi/linux/sync_file.h +++ b/include/uapi/linux/sync_file.h @@ -69,6 +69,26 @@ struct sync_file_info { #define SYNC_IOC_MAGIC '>' /** + * DOC: SYNC_FILE_TYPE_FENCE - fence sync file object + * + * This sync file is a wrapper around a dma fence or a dma fence array. + * It can be merged with another fence sync file object to create a new + * merged object. + * The fence backing this object cannot be replaced. + * This is useful for shared fences. + */ +#define SYNC_FILE_TYPE_FENCE 0 + +/** + * struct sync_file_type - data returned from sync file type ioctl + * @type: sync_file type + * @flags: sync_file creation flags + */ +struct sync_file_type { + __u32 type; + __u32 flags; +}; +/** * Opcodes 0, 1 and 2 were burned during a API change to avoid users of the * old API to get weird errors when trying to handling sync_files. The API * change happened during the de-stage of the Sync Framework when there was @@ -94,4 +114,11 @@ struct sync_file_info { */ #define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info) +/** + * DOC: SYNC_IOC_TYPE - get creation type and flags of sync_file. + * + * Takes a struct sync_file_type. Returns the created values of type and flags. + */ +#define SYNC_IOC_TYPE _IOWR(SYNC_IOC_MAGIC, 5, struct sync_file_type) + #endif /* _UAPI_LINUX_SYNC_H */