* [PATCH] dma-buf: Implement simple read/write vfs ops
@ 2017-04-07 19:32 Chris Wilson
2017-04-07 21:25 ` [PATCH v2] " Chris Wilson
0 siblings, 1 reply; 7+ messages in thread
From: Chris Wilson @ 2017-04-07 19:32 UTC (permalink / raw)
To: dri-devel; +Cc: Daniel Vetter
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.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Laura Abbott <labbott@redhat.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Sean Paul <seanpaul@chromium.org>
---
drivers/dma-buf/dma-buf.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 1ce7974a28a3..e4388d5258ed 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -124,6 +124,92 @@ static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence)
return base + offset;
}
+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 written;
+
+ if (!is_dma_buf_file(file))
+ return -EBADF;
+
+ written = 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;
+
+ vaddr = dma_buf_kmap(dmabuf, idx);
+ if (!vaddr)
+ return written ?: -EIO;
+
+ copied = copy_to_user(vaddr, ubuf, len);
+ dma_buf_kunmap(dmabuf, idx, vaddr);
+
+ written += copied ?: len;
+ if (copied) {
+ *offset += copied;
+ return written ?: -EFAULT;
+ }
+
+ remain -= len;
+ *offset += len;
+ ubuf += len;
+ start = 0;
+ idx++;
+ }
+
+ return written;
+}
+
+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 written;
+
+ if (!is_dma_buf_file(file))
+ return -EBADF;
+
+ written = 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;
+
+ vaddr = dma_buf_kmap(dmabuf, idx);
+ if (!vaddr)
+ return written ?: -EIO;
+
+ copied = copy_from_user(vaddr, ubuf, len);
+ dma_buf_kunmap(dmabuf, idx, vaddr);
+
+ written += copied ?: len;
+ if (copied) {
+ *offset += copied;
+ return written ?: -EFAULT;
+ }
+
+ remain -= len;
+ *offset += len;
+ ubuf += len;
+ start = 0;
+ idx++;
+ }
+
+ return written;
+}
+
/**
* DOC: fence polling
*
@@ -318,6 +404,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
--
2.11.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2] dma-buf: Implement simple read/write vfs ops
2017-04-07 19:32 [PATCH] dma-buf: Implement simple read/write vfs ops Chris Wilson
@ 2017-04-07 21:25 ` Chris Wilson
2017-04-12 18:29 ` Laura Abbott
0 siblings, 1 reply; 7+ messages in thread
From: Chris Wilson @ 2017-04-07 21:25 UTC (permalink / raw)
To: dri-devel; +Cc: Daniel Vetter
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 <chris@chris-wilson.co.uk>
Cc: Laura Abbott <labbott@redhat.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Sean Paul <seanpaul@chromium.org>
---
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
--
2.11.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2] dma-buf: Implement simple read/write vfs ops
2017-04-07 21:25 ` [PATCH v2] " Chris Wilson
@ 2017-04-12 18:29 ` Laura Abbott
2017-04-12 19:38 ` Chris Wilson
0 siblings, 1 reply; 7+ messages in thread
From: Laura Abbott @ 2017-04-12 18:29 UTC (permalink / raw)
To: Chris Wilson, dri-devel; +Cc: Daniel Vetter
On 04/07/2017 02:25 PM, Chris Wilson wrote:
> 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 <chris@chris-wilson.co.uk>
> Cc: Laura Abbott <labbott@redhat.com>
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Sean Paul <seanpaul@chromium.org>
> ---
> 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;
> }
>
Both the read/write are missing the dma_buf_begin_cpu_access calls.
When I add those these seem to work well enough for a simple
test. I can add a real Tested-by for the next version.
Thanks,
Laura
> /**
> @@ -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
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] dma-buf: Implement simple read/write vfs ops
2017-04-12 18:29 ` Laura Abbott
@ 2017-04-12 19:38 ` Chris Wilson
2017-04-12 19:57 ` Laura Abbott
0 siblings, 1 reply; 7+ messages in thread
From: Chris Wilson @ 2017-04-12 19:38 UTC (permalink / raw)
To: Laura Abbott; +Cc: Daniel Vetter, dri-devel
On Wed, Apr 12, 2017 at 11:29:18AM -0700, Laura Abbott wrote:
> On 04/07/2017 02:25 PM, Chris Wilson wrote:
> > 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 <chris@chris-wilson.co.uk>
> > Cc: Laura Abbott <labbott@redhat.com>
> > Cc: Sumit Semwal <sumit.semwal@linaro.org>
> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Cc: Sean Paul <seanpaul@chromium.org>
> > ---
> > 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;
> > }
> >
>
> Both the read/write are missing the dma_buf_begin_cpu_access calls.
> When I add those these seem to work well enough for a simple
> test. I can add a real Tested-by for the next version.
Correct, that was intentional to leave synchronisation to be managed by
the caller. It is easier to add synchronisation than take it away.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] dma-buf: Implement simple read/write vfs ops
2017-04-12 19:38 ` Chris Wilson
@ 2017-04-12 19:57 ` Laura Abbott
2017-04-12 20:12 ` Chris Wilson
0 siblings, 1 reply; 7+ messages in thread
From: Laura Abbott @ 2017-04-12 19:57 UTC (permalink / raw)
To: Chris Wilson, dri-devel, Sumit Semwal, Daniel Vetter, Sean Paul
On 04/12/2017 12:38 PM, Chris Wilson wrote:
> On Wed, Apr 12, 2017 at 11:29:18AM -0700, Laura Abbott wrote:
>> On 04/07/2017 02:25 PM, Chris Wilson wrote:
>>> 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 <chris@chris-wilson.co.uk>
>>> Cc: Laura Abbott <labbott@redhat.com>
>>> Cc: Sumit Semwal <sumit.semwal@linaro.org>
>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>>> Cc: Sean Paul <seanpaul@chromium.org>
>>> ---
>>> 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;
>>> }
>>>
>>
>> Both the read/write are missing the dma_buf_begin_cpu_access calls.
>> When I add those these seem to work well enough for a simple
>> test. I can add a real Tested-by for the next version.
>
> Correct, that was intentional to leave synchronisation to be managed by
> the caller. It is easier to add synchronisation than take it away.
> -Chris
>
Ah yes, that makes sense. This is what the sync ioctls were for in
the first place :). You can add
Tested-by: Laura Abbott <labbott@redhat.com>
Thanks,
Laura
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] dma-buf: Implement simple read/write vfs ops
2017-04-12 19:57 ` Laura Abbott
@ 2017-04-12 20:12 ` Chris Wilson
2017-04-12 20:35 ` Laura Abbott
0 siblings, 1 reply; 7+ messages in thread
From: Chris Wilson @ 2017-04-12 20:12 UTC (permalink / raw)
To: Laura Abbott; +Cc: Daniel Vetter, dri-devel
On Wed, Apr 12, 2017 at 12:57:00PM -0700, Laura Abbott wrote:
> On 04/12/2017 12:38 PM, Chris Wilson wrote:
> > On Wed, Apr 12, 2017 at 11:29:18AM -0700, Laura Abbott wrote:
> >> Both the read/write are missing the dma_buf_begin_cpu_access calls.
> >> When I add those these seem to work well enough for a simple
> >> test. I can add a real Tested-by for the next version.
> >
> > Correct, that was intentional to leave synchronisation to be managed by
> > the caller. It is easier to add synchronisation than take it away.
> > -Chris
> >
>
> Ah yes, that makes sense. This is what the sync ioctls were for in
> the first place :). You can add
>
> Tested-by: Laura Abbott <labbott@redhat.com>
Back to the main point of the exercise, does this fulfil the needs for
ion/dmabuf testing?
We have mmap and now kmap coverage, just by using dmabuf fops - but I
can't see a reasonable avenue to do vmap testing.
And you will still want vgem for import testing. Again, I can't see a
good excuse for vmap...
Do you have a set of kselftests in conjunction to userspace testing?
Would it be worth making a common mock_dmabuf.ko and/or a dmabuf
kselftest framework for producers/consumers to plug into their own
kselftests? Please stop me if I'm overengineering!
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] dma-buf: Implement simple read/write vfs ops
2017-04-12 20:12 ` Chris Wilson
@ 2017-04-12 20:35 ` Laura Abbott
0 siblings, 0 replies; 7+ messages in thread
From: Laura Abbott @ 2017-04-12 20:35 UTC (permalink / raw)
To: Chris Wilson, dri-devel, Sumit Semwal, Daniel Vetter, Sean Paul
On 04/12/2017 01:12 PM, Chris Wilson wrote:
> On Wed, Apr 12, 2017 at 12:57:00PM -0700, Laura Abbott wrote:
>> On 04/12/2017 12:38 PM, Chris Wilson wrote:
>>> On Wed, Apr 12, 2017 at 11:29:18AM -0700, Laura Abbott wrote:
>>>> Both the read/write are missing the dma_buf_begin_cpu_access calls.
>>>> When I add those these seem to work well enough for a simple
>>>> test. I can add a real Tested-by for the next version.
>>>
>>> Correct, that was intentional to leave synchronisation to be managed by
>>> the caller. It is easier to add synchronisation than take it away.
>>> -Chris
>>>
>>
>> Ah yes, that makes sense. This is what the sync ioctls were for in
>> the first place :). You can add
>>
>> Tested-by: Laura Abbott <labbott@redhat.com>
>
> Back to the main point of the exercise, does this fulfil the needs for
> ion/dmabuf testing?
>
> We have mmap and now kmap coverage, just by using dmabuf fops - but I
> can't see a reasonable avenue to do vmap testing.
>
> And you will still want vgem for import testing. Again, I can't see a
> good excuse for vmap...
>
Yes, this should be good for Ion testing. Ion doesn't implement
vmap ops right now so that's moot...
> Do you have a set of kselftests in conjunction to userspace testing?
> Would it be worth making a common mock_dmabuf.ko and/or a dmabuf
> kselftest framework for producers/consumers to plug into their own
> kselftests? Please stop me if I'm overengineering!
> -Chris
>
...but in the interest of general testing I think getting some
sort of unit test would be good. I don't have anything in kernel
yet for Ion so maybe some generic dma_buf test would be useful.
I'll see what I come up with.
Thanks,
Laura
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-04-12 20:35 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-07 19:32 [PATCH] dma-buf: Implement simple read/write vfs ops Chris Wilson
2017-04-07 21:25 ` [PATCH v2] " Chris Wilson
2017-04-12 18:29 ` Laura Abbott
2017-04-12 19:38 ` Chris Wilson
2017-04-12 19:57 ` Laura Abbott
2017-04-12 20:12 ` Chris Wilson
2017-04-12 20:35 ` Laura Abbott
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.