From patchwork Mon Jul 11 21:59:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 9224333 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 6733460760 for ; Mon, 11 Jul 2016 21:59:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 588BF27E15 for ; Mon, 11 Jul 2016 21:59:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4CB0527EED; Mon, 11 Jul 2016 21:59:55 +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.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4D0BE27E15 for ; Mon, 11 Jul 2016 21:59:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A975B6E1E1; Mon, 11 Jul 2016 21:59:51 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x244.google.com (mail-wm0-x244.google.com [IPv6:2a00:1450:400c:c09::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 423156E1E1 for ; Mon, 11 Jul 2016 21:59:49 +0000 (UTC) Received: by mail-wm0-x244.google.com with SMTP id w75so42637wmd.1 for ; Mon, 11 Jul 2016 14:59:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id; bh=i+qqtXtIOI9qe5FDOpKgFUKHQkRjLm9hMUJnyQGbvJA=; b=wKcTNExf964g3NFNq3Z/asy7wdYIjBlR9gfQGgkWeTiZ99zKhokKDCeNR90ZZe1gaq VJfpgEPdra4jp4Ea47T0bh0QsWyq7lFdoy56iACKp3nC0BQpkrIpKnrv5c8cUvZm3bZ/ Lk6ycFvMrw5Mo1uK261ipvYWT5tIPHOZvBXZsPYLCbDSIncCniVieEB2oiKTegeLrHGp 7TUGRN4ajHiMPcN1r86EZO0kfMFT13uo26U48cX6AUYeC9EwKWpsWe9OErM/nZTkGzF1 vN2GcjsgrqejLtPyWf81c1Pir9/GO94NuFxXZH20VHey0dIgewDg1eiajr3mM+KQ5DcD H+Xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=i+qqtXtIOI9qe5FDOpKgFUKHQkRjLm9hMUJnyQGbvJA=; b=V9+adbzoTzaPMzoylN5WUC3NwSgG+tNH6HyksEhtuOB4jZ4TT5jTLmn+GJNR091DdU vYL1A2pOMamnkd4MMG1ls44ZcT+2jNabislfLNn7KLcU5U09vpiTWjmARUWLb0mFYxZI 7E8AYEVsaesELqQja+ExYcdBbNWuaxjCtweWVJmK7MIrwfF1r4IGNgCB2U/V2TQUCGBn UoPsVKrkuxFcd/tm53uC+dwjjQ+4BslZLj57DIvCaPT0WLu04RmWGLy01r28gNUzg6J9 573EPkDmqy4pVDT6VkNHf9++xXin5NutYYNgjWvtJ29oEMcZ1dRd7hMPiH9ixXKlQ9El TEIw== X-Gm-Message-State: ALyK8tI+/VU2Uk35UPGk8+9OOjxh3e9mX7JdtMmybtuvpnUSBKFA/My2WdIwuHqRAPoaNQ== X-Received: by 10.28.154.21 with SMTP id c21mr14557005wme.63.1468274387584; Mon, 11 Jul 2016 14:59:47 -0700 (PDT) Received: from haswell.alporthouse.com ([78.156.65.138]) by smtp.gmail.com with ESMTPSA id x194sm25129664wmf.13.2016.07.11.14.59.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Jul 2016 14:59:46 -0700 (PDT) From: Chris Wilson To: dri-devel@lists.freedesktop.org Subject: [RFC] dma-buf: Import/export the implicit fences on the dma-buf Date: Mon, 11 Jul 2016 22:59:38 +0100 Message-Id: <1468274378-23081-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.8.1 Cc: Daniel Vetter , Gustavo Padovan 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: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP When dealing with user interfaces that utilize explicit fences, it is convenient to sometimes create those fences after the fact, i.e. to query the dma-buf for the current set of implicit fences, encapsulate those into a sync_file and hand that fd back to userspace. Correspondingly, being able to add an explicit fence back into the mix of fences being tracked by the dma-buf allows that userspace fence to be included in any implicit tracking. Signed-off-by: Chris Wilson Cc: Gustavo Padovan Cc: Rob Clark Cc: Sumit Semwal Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org --- Gustavo, could you look at the sync-file/fence-array handling? There's definitely room for a cleaner sync_file_create() API. I was thinking about this for the "why not sync-file" question Gustavo posed for the vgem_fences. I wanted to add an ioctl to the vgem to allow exporting and creating fences from sync-file for testing passing explicit userspaces around between drivers, and realised that I was just writing a generic mechanism that only required dma-buf. Whilst this interface could be used for lazily creating explicit fences, drivers will also likely want to support specific ioctl to skip the dmabuf creation, I think this interfaces will be useful with the vgem fences for testing sync_file handling in drivers (on i915 at the moment, my tests for sync_file involve sleeping and a few white lies). So fulfilling a similar role in driver testing to debugfs/sw_sync? (sw_sync is still more apt for testing timelines etc, vgem feels more apt for ease of testing rendering.) -Chris --- drivers/dma-buf/dma-buf.c | 100 +++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/dma-buf.h | 9 ++++ 2 files changed, 109 insertions(+) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 41fbce0c273a..6f066a8affd7 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -26,11 +26,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -254,6 +256,97 @@ out: return events; } +static long dma_buf_import_fence_ioctl(struct dma_buf *dmabuf, + struct dma_buf_fence __user *arg) +{ + struct reservation_object *resv = dmabuf->resv; + struct dma_buf_fence cmd; + struct fence *fence; + int ret; + + if (copy_from_user(&cmd, arg, sizeof(cmd))) + return -EFAULT; + + fence = NULL; + //fence = sync_file_get_fence(cmd.fd); + if (!fence) + return -EINVAL; + + mutex_lock(&resv->lock.base); + if (cmd.flags & DMA_BUF_FENCE_WRITE) + reservation_object_add_excl_fence(resv, fence); + else if ((ret = reservation_object_reserve_shared(resv)) == 0) + reservation_object_add_shared_fence(resv, fence); + mutex_unlock(&resv->lock.base); + + fence_put(fence); + return ret; +} + +static long dma_buf_export_fence_ioctl(struct dma_buf *dmabuf, + struct dma_buf_fence __user *arg) +{ + struct reservation_object *resv = dmabuf->resv; + struct dma_buf_fence cmd; + struct fence *excl, **shared; + struct sync_file *sync = NULL; + unsigned int count, n; + int ret; + + if (get_user(cmd.flags, &arg->flags)) + return -EFAULT; + + ret = reservation_object_get_fences_rcu(resv, &excl, &count, &shared); + if (ret) + return ret; + + if (cmd.flags & DMA_BUF_FENCE_WRITE) { + if (excl) { + sync = sync_file_create(excl); + if (!sync) { + ret = -ENOMEM; + fence_put(excl); + } + } + for (n = 0; n < count; n++) + fence_put(shared[n]); + kfree(shared); + } else { + if (count) { + struct fence_array *array; + + array = fence_array_create(count, shared, 0, 0, false); + if (!array) { + for (n = 0; n < count; n++) + fence_put(shared[n]); + kfree(shared); + } else + sync = sync_file_create(&array->base); + if (!sync) { + ret = -ENOMEM; + fence_put(&array->base); + } + } + fence_put(excl); + } + if (ret) + return ret; + + cmd.fd = get_unused_fd_flags(O_CLOEXEC); + if (cmd.fd < 0) { + fput(sync->file); + return cmd.fd; + } + + if (put_user(cmd.fd, &arg->fd)) { + fput(sync->file); + return -EFAULT; + } + + fd_install(cmd.fd, sync->file); + return 0; +} + static long dma_buf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -292,6 +385,13 @@ static long dma_buf_ioctl(struct file *file, ret = dma_buf_begin_cpu_access(dmabuf, direction); return ret; + + case DMA_BUF_IOCTL_IMPORT_FENCE: + return dma_buf_import_fence_ioctl(dmabuf, (void __user *)arg); + + case DMA_BUF_IOCTL_EXPORT_FENCE: + return dma_buf_export_fence_ioctl(dmabuf, (void __user *)arg); + default: return -ENOTTY; } diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h index fb0dedb7c121..8d9a0d73ebaa 100644 --- a/include/uapi/linux/dma-buf.h +++ b/include/uapi/linux/dma-buf.h @@ -37,4 +37,13 @@ struct dma_buf_sync { #define DMA_BUF_BASE 'b' #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) +struct dma_buf_fence { + __s32 fd; + __u32 flags; +#define DMA_BUF_FENCE_WRITE (1 << 0) +}; + +#define DMA_BUF_IOCTL_IMPORT_FENCE _IOW(DMA_BUF_BASE, 1, struct dma_buf_fence) +#define DMA_BUF_IOCTL_EXPORT_FENCE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_fence) + #endif