From patchwork Fri Apr 7 21:25:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 9670493 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 4978E602A0 for ; Fri, 7 Apr 2017 21:25:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 398F024603 for ; Fri, 7 Apr 2017 21:25:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2D0962865C; Fri, 7 Apr 2017 21:25:21 +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]) (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 972D924603 for ; Fri, 7 Apr 2017 21:25:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 651A56ED6F; Fri, 7 Apr 2017 21:25:19 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wr0-x241.google.com (mail-wr0-x241.google.com [IPv6:2a00:1450:400c:c0c::241]) by gabe.freedesktop.org (Postfix) with ESMTPS id 571A06ED6F for ; Fri, 7 Apr 2017 21:25:18 +0000 (UTC) Received: by mail-wr0-x241.google.com with SMTP id g19so21815387wrb.0 for ; Fri, 07 Apr 2017 14:25:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=OGJQjhNhc2gJ00x8wPozcgd7VJEHKAegcstfCjLs6p0=; b=K2OGUTuB3tL4YyihRRhHnNM/A4htK2djvLjlpe4IsTgtz+kg8I5jHqrTdXJWLGhMXZ zna5kMk4vj8a3x6BpU0J8ICSShmyGY2WUANIQxWav3KFnGS9XYoT1Fim98Kg6nIbRQ7q OpCCz6MlQuuss/eBiBmyHE8KGmCzs42oi894XmDt9A/n6w9e6kgWGyxPgwoANb0SPVxI cKOX3yNCwo569NUK514IDX3po93uCvck882siGFxoDQJ5J393RufvSiUjWi01Ksff70/ NWce1ikpUunqIhZ0pU2ERrZIiovtPFGeB9wsBVJ/HFM54+cANKALxr+DOncl/WakxhwJ Qqtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=OGJQjhNhc2gJ00x8wPozcgd7VJEHKAegcstfCjLs6p0=; b=OjCha2BnCbVWKiAwPNrxCZYrmpSMgK5j+tfhUG9TIuEqabS6KAG971XxgpL3Bkomck 79pgn1FQjXRQxElL88T9LXh0G/UpJBKiMrBgVuz115IsEQHiK2GySyJOEnyoUAnX+SO/ WptkvQ2bLq+7+aqbAbAVvoulMQTUb5d9h0bP4/1Bg/qBra576vERZVRYUHW4DmsdoCO3 3sFSZNZbV52BzTT6SJXwidt8k8897CZEPlHrrQ5QQ4NwbcnnhahF010mFLN0NQXxddCr DsSx2Mfz3qeDec464Jw6f+9zbtRhH3bbFwRYHbxY6NVhflHpLJThqhaE9ILozGTm/yjG N7xw== X-Gm-Message-State: AFeK/H3XJKZywPpbV0pzzj7r4RDWQJrAI5Vq/7rp7MYyCjpSRpc1xYxouJAMRQzLHFJhkw== X-Received: by 10.223.129.198 with SMTP id 64mr11353364wra.193.1491600317032; Fri, 07 Apr 2017 14:25:17 -0700 (PDT) Received: from haswell.alporthouse.com ([78.156.65.138]) by smtp.gmail.com with ESMTPSA id v14sm7374650wra.65.2017.04.07.14.25.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Apr 2017 14:25:16 -0700 (PDT) From: Chris Wilson To: dri-devel@lists.freedesktop.org Subject: [PATCH v2] dma-buf: Implement simple read/write vfs ops Date: Fri, 7 Apr 2017 22:25:14 +0100 Message-Id: <20170407212514.1487-1-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170407193208.678-1-chris@chris-wilson.co.uk> References: <20170407193208.678-1-chris@chris-wilson.co.uk> Cc: Daniel Vetter 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 It is expected that processes will pass dma-buf fd between drivers, and only using the fd themselves for mmaping and synchronisation ioctls. However, it may be convenient for an application to read/write into the dma-buf, for instance a test case to check the internal dma_buf->ops->kmap interface. There may also be a small advantage to avoiding the mmap() for very simple/small operations. Note in particular, synchronisation with the device is left to the caller with an explicit DMA_BUF_IOCTL_SYNC, rather than done implicitly inside the read/write, so that the user can avoid synchronisation if they so choose. v2: Lots of little fixes, plus a real llseek() implements so that the first basic little test cases work! Testcase: igt/prime_rw Signed-off-by: Chris Wilson Cc: Laura Abbott Cc: Sumit Semwal Cc: Daniel Vetter Cc: Sean Paul Tested-by: Laura Abbott --- drivers/dma-buf/dma-buf.c | 108 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 15 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 1ce7974a28a3..6e6e35c660c7 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -100,28 +100,104 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence) { - struct dma_buf *dmabuf; - loff_t base; + struct dma_buf *dmabuf = file->private_data; if (!is_dma_buf_file(file)) return -EBADF; - dmabuf = file->private_data; + return fixed_size_llseek(file, offset, whence, dmabuf->size); +} - /* only support discovering the end of the buffer, - but also allow SEEK_SET to maintain the idiomatic - SEEK_END(0), SEEK_CUR(0) pattern */ - if (whence == SEEK_END) - base = dmabuf->size; - else if (whence == SEEK_SET) - base = 0; - else - return -EINVAL; +static ssize_t dma_buf_read(struct file *file, + char __user *ubuf, size_t remain, + loff_t *offset) +{ + struct dma_buf *dmabuf = file->private_data; + unsigned long idx; + unsigned int start; + size_t total; - if (offset != 0) - return -EINVAL; + if (!is_dma_buf_file(file)) + return -EBADF; + + total = 0; + idx = *offset >> PAGE_SHIFT; + start = offset_in_page(*offset); + while (remain) { + unsigned int len = min_t(size_t, remain, PAGE_SIZE - start); + unsigned int copied; + void *vaddr; + + if (*offset >= dmabuf->size) + return total; + + vaddr = dma_buf_kmap(dmabuf, idx); + if (!vaddr) + return total ?: -EIO; + + copied = copy_to_user(ubuf, vaddr + start, len); + dma_buf_kunmap(dmabuf, idx, vaddr); + + total += copied ?: len; + if (copied) { + *offset += copied; + return total ?: -EFAULT; + } + + remain -= len; + *offset += len; + ubuf += len; + start = 0; + idx++; + } + + return total; +} + +static ssize_t dma_buf_write(struct file *file, + const char __user *ubuf, size_t remain, + loff_t *offset) +{ + struct dma_buf *dmabuf = file->private_data; + unsigned long idx; + unsigned int start; + size_t total; + + if (!is_dma_buf_file(file)) + return -EBADF; + + total = 0; + idx = *offset >> PAGE_SHIFT; + start = offset_in_page(*offset); + while (remain) { + unsigned int len = min_t(size_t, remain, PAGE_SIZE - start); + unsigned int copied; + void *vaddr; + + if (*offset >= dmabuf->size) + return total; + + vaddr = dma_buf_kmap(dmabuf, idx); + if (!vaddr) + return total ?: -EIO; + + copied = copy_from_user(vaddr + start, ubuf, len); + dma_buf_kunmap(dmabuf, idx, vaddr); + + total += copied ?: len; + if (copied) { + *offset += copied; + return total ?: -EFAULT; + } + + remain -= len; + *offset += len; + ubuf += len; + start = 0; + idx++; + } - return base + offset; + return total; } /** @@ -318,6 +394,8 @@ static const struct file_operations dma_buf_fops = { .release = dma_buf_release, .mmap = dma_buf_mmap_internal, .llseek = dma_buf_llseek, + .read = dma_buf_read, + .write = dma_buf_write, .poll = dma_buf_poll, .unlocked_ioctl = dma_buf_ioctl, #ifdef CONFIG_COMPAT