Re: [PATCH 2/7] v4l: videobuf2: add generic memory handling routines

2010-11-29 Thread Laurent Pinchart
Hi Marek,

On Friday 19 November 2010 16:55:39 Marek Szyprowski wrote:
 From: Pawel Osciak p.osc...@samsung.com
 
 Add generic memory handling routines for userspace pointer handling,
 contiguous memory verification and mapping.
 
 Signed-off-by: Pawel Osciak p.osc...@samsung.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 CC: Pawel Osciak pa...@osciak.com
 ---
  drivers/media/video/Kconfig|3 +
  drivers/media/video/Makefile   |1 +
  drivers/media/video/videobuf2-memops.c |  199
  include/media/videobuf2-memops.h   | 
  31 +
  4 files changed, 234 insertions(+), 0 deletions(-)
  create mode 100644 drivers/media/video/videobuf2-memops.c
  create mode 100644 include/media/videobuf2-memops.h
 
 diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
 index fef6a14..83ce858 100644
 --- a/drivers/media/video/Kconfig
 +++ b/drivers/media/video/Kconfig
 @@ -52,6 +52,9 @@ config V4L2_MEM2MEM_DEV
  config VIDEOBUF2_CORE
   tristate
 
 +config VIDEOBUF2_MEMOPS
 + tristate
 +
  #
  # Multimedia Video device configuration
  #
 diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
 index 77c4f85..a97a2a0 100644
 --- a/drivers/media/video/Makefile
 +++ b/drivers/media/video/Makefile
 @@ -115,6 +115,7 @@ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
  obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
 
  obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o
 +obj-$(CONFIG_VIDEOBUF2_MEMOPS)   += videobuf2-memops.o
 
  obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
 
 diff --git a/drivers/media/video/videobuf2-memops.c
 b/drivers/media/video/videobuf2-memops.c new file mode 100644
 index 000..67ebdff
 --- /dev/null
 +++ b/drivers/media/video/videobuf2-memops.c
 @@ -0,0 +1,199 @@
 +/*
 + * videobuf2-memops.c - generic memory handling routines for videobuf2
 + *
 + * Copyright (C) 2010 Samsung Electronics
 + *
 + * Author: Pawel Osciak p.osc...@samsung.com
 + *  Marek Szyprowski m.szyprow...@samsung.com
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
 + * the Free Software Foundation.
 + */
 +
 +#include linux/slab.h
 +#include linux/module.h
 +#include linux/dma-mapping.h
 +#include linux/vmalloc.h
 +#include linux/cma.h
 +#include linux/mm.h
 +#include linux/sched.h
 +#include linux/file.h
 +
 +#include media/videobuf2-core.h
 +
 +/**
 + * vb2_contig_verify_userptr() - verify contiguity of a userspace-mapped
 memory + * @vma:  virtual memory region which maps the physical memory
 + *   to be verified
 + * @vaddr:   starting virtual address of the area to be verified
 + * @size:size of the area to be verified
 + * @paddr:   will return physical address for the given vaddr
 + *
 + * This function will go through memory area of size size mapped at vaddr
 and + * verify that the underlying physical pages are contiguous.
 + *
 + * Returns 0 on success and a physical address to the memory pointed
 + * to by vaddr in paddr.
 + */
 +int vb2_contig_verify_userptr(struct vm_area_struct *vma,
 + unsigned long vaddr, unsigned long size,
 + unsigned long *paddr)
 +{
 + struct mm_struct *mm = current-mm;
 + unsigned long offset;
 + unsigned long vma_size;
 + unsigned long curr_pfn, prev_pfn;
 + unsigned long num_pages;
 + int ret = -EINVAL;
 + unsigned int i;
 +
 + offset = vaddr  ~PAGE_MASK;
 +
 + down_read(mm-mmap_sem);
 +
 + vma = find_vma(mm, vaddr);

You're overwriting the vma argument, why do you need it ?

 + if (!vma) {
 + printk(KERN_ERR Invalid userspace address\n);
 + goto done;
 + }
 +
 + vma_size = vma-vm_end - vma-vm_start;
 +
 + if (size  vma_size - offset) {
 + printk(KERN_ERR Region too small\n);
 + goto done;
 + }
 + num_pages = (size + offset)  PAGE_SHIFT;
 +
 + ret = follow_pfn(vma, vaddr, curr_pfn);

Maybe you could put this call in the loop to avoid code duplication ? Feel 
free to steal code from 
http://git.linuxtv.org/pinchartl/media.git?a=blob;f=drivers/media/video/isp/ispqueue.c;h=6750f68a6476fc168d44563b332f6b23b2700504;hb=630004a88986b1f8b42c5fddb9a5e5c0d575b464#l358
 
:-)

 + if (ret) {
 + printk(KERN_ERR Invalid userspace address\n);
 + goto done;
 + }
 +
 + *paddr = (curr_pfn  PAGE_SHIFT) + offset;
 +
 + for (i = 1; i  num_pages; ++i) {
 + prev_pfn = curr_pfn;
 + vaddr += PAGE_SIZE;
 +
 + ret = follow_pfn(vma, vaddr, curr_pfn);
 + if (ret || curr_pfn != prev_pfn + 1) {
 + printk(KERN_ERR Invalid userspace address\n);
 + ret = -EINVAL;

I would use -EFAULT when curr_pfn != prev_pfn + 1.

 +   

RE: [PATCH 2/7] v4l: videobuf2: add generic memory handling routines

2010-11-29 Thread Marek Szyprowski
Hello,

On Monday, November 29, 2010 10:39 AM Laurent Pinchart wrote:

 Hi Marek,
 
 On Friday 19 November 2010 16:55:39 Marek Szyprowski wrote:
  From: Pawel Osciak p.osc...@samsung.com
 
  Add generic memory handling routines for userspace pointer handling,
  contiguous memory verification and mapping.
 
  Signed-off-by: Pawel Osciak p.osc...@samsung.com
  Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
  Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
  CC: Pawel Osciak pa...@osciak.com
  ---
   drivers/media/video/Kconfig|3 +
   drivers/media/video/Makefile   |1 +
   drivers/media/video/videobuf2-memops.c |  199
   include/media/videobuf2-memops.h   |
   31 +
   4 files changed, 234 insertions(+), 0 deletions(-)
   create mode 100644 drivers/media/video/videobuf2-memops.c
   create mode 100644 include/media/videobuf2-memops.h
 
  diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
  index fef6a14..83ce858 100644
  --- a/drivers/media/video/Kconfig
  +++ b/drivers/media/video/Kconfig
  @@ -52,6 +52,9 @@ config V4L2_MEM2MEM_DEV
   config VIDEOBUF2_CORE
  tristate
 
  +config VIDEOBUF2_MEMOPS
  +   tristate
  +
   #
   # Multimedia Video device configuration
   #
  diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
  index 77c4f85..a97a2a0 100644
  --- a/drivers/media/video/Makefile
  +++ b/drivers/media/video/Makefile
  @@ -115,6 +115,7 @@ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
   obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
 
   obj-$(CONFIG_VIDEOBUF2_CORE)   += videobuf2-core.o
  +obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
 
   obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
 
  diff --git a/drivers/media/video/videobuf2-memops.c
  b/drivers/media/video/videobuf2-memops.c new file mode 100644
  index 000..67ebdff
  --- /dev/null
  +++ b/drivers/media/video/videobuf2-memops.c
  @@ -0,0 +1,199 @@
  +/*
  + * videobuf2-memops.c - generic memory handling routines for videobuf2
  + *
  + * Copyright (C) 2010 Samsung Electronics
  + *
  + * Author: Pawel Osciak p.osc...@samsung.com
  + *Marek Szyprowski m.szyprow...@samsung.com
  + *
  + * This program is free software; you can redistribute it and/or modify
  + * it under the terms of the GNU General Public License as published by
  + * the Free Software Foundation.
  + */
  +
  +#include linux/slab.h
  +#include linux/module.h
  +#include linux/dma-mapping.h
  +#include linux/vmalloc.h
  +#include linux/cma.h
  +#include linux/mm.h
  +#include linux/sched.h
  +#include linux/file.h
  +
  +#include media/videobuf2-core.h
  +
  +/**
  + * vb2_contig_verify_userptr() - verify contiguity of a userspace-mapped
  memory + * @vma:virtual memory region which maps the physical memory
  + * to be verified
  + * @vaddr: starting virtual address of the area to be verified
  + * @size:  size of the area to be verified
  + * @paddr: will return physical address for the given vaddr
  + *
  + * This function will go through memory area of size size mapped at vaddr
  and + * verify that the underlying physical pages are contiguous.
  + *
  + * Returns 0 on success and a physical address to the memory pointed
  + * to by vaddr in paddr.
  + */
  +int vb2_contig_verify_userptr(struct vm_area_struct *vma,
  +   unsigned long vaddr, unsigned long size,
  +   unsigned long *paddr)
  +{
  +   struct mm_struct *mm = current-mm;
  +   unsigned long offset;
  +   unsigned long vma_size;
  +   unsigned long curr_pfn, prev_pfn;
  +   unsigned long num_pages;
  +   int ret = -EINVAL;
  +   unsigned int i;
  +
  +   offset = vaddr  ~PAGE_MASK;
  +
  +   down_read(mm-mmap_sem);
  +
  +   vma = find_vma(mm, vaddr);
 
 You're overwriting the vma argument, why do you need it ?

Well, I'm sorry for this. Looks I've missed something here. I will fix this in 
the next version.
 
  +   if (!vma) {
  +   printk(KERN_ERR Invalid userspace address\n);
  +   goto done;
  +   }
  +
  +   vma_size = vma-vm_end - vma-vm_start;
  +
  +   if (size  vma_size - offset) {
  +   printk(KERN_ERR Region too small\n);
  +   goto done;
  +   }
  +   num_pages = (size + offset)  PAGE_SHIFT;
  +
  +   ret = follow_pfn(vma, vaddr, curr_pfn);
 
 Maybe you could put this call in the loop to avoid code duplication ? Feel
 free to steal code from
 http://git.linuxtv.org/pinchartl/media.git?a=blob;f=drivers/media/video/isp/ispqueue.c;h=6750f68a6476f
 c168d44563b332f6b23b2700504;hb=630004a88986b1f8b42c5fddb9a5e5c0d575b464#l358
 :-)

Ok, Thx :)

 
  +   if (ret) {
  +   printk(KERN_ERR Invalid userspace address\n);
  +   goto done;
  +   }
  +
  +   *paddr = (curr_pfn  PAGE_SHIFT) + offset;
  +
  +   for (i = 1; i  num_pages; ++i) {
  +   prev_pfn = curr_pfn;
  +   vaddr += PAGE_SIZE;
  +
  +   ret = follow_pfn(vma, 

Re: [PATCH 2/7] v4l: videobuf2: add generic memory handling routines

2010-11-29 Thread Laurent Pinchart
Hi Marek,

On Monday 29 November 2010 14:24:35 Marek Szyprowski wrote:
 On Monday, November 29, 2010 10:39 AM Laurent Pinchart wrote:
  On Friday 19 November 2010 16:55:39 Marek Szyprowski wrote:
   From: Pawel Osciak p.osc...@samsung.com
   
   Add generic memory handling routines for userspace pointer handling,
   contiguous memory verification and mapping.
   
   Signed-off-by: Pawel Osciak p.osc...@samsung.com
   Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
   Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
   CC: Pawel Osciak pa...@osciak.com

[snip]

   + if (ret) {
   + printk(KERN_ERR Invalid userspace address\n);
   + goto done;
   + }
   +
   + *paddr = (curr_pfn  PAGE_SHIFT) + offset;
   +
   + for (i = 1; i  num_pages; ++i) {
   + prev_pfn = curr_pfn;
   + vaddr += PAGE_SIZE;
   +
   + ret = follow_pfn(vma, vaddr, curr_pfn);
   + if (ret || curr_pfn != prev_pfn + 1) {
   + printk(KERN_ERR Invalid userspace address\n);
   + ret = -EINVAL;
  
  I would use -EFAULT when curr_pfn != prev_pfn + 1.
 
 I don't think that this situation desires for a EFAULT error code. EINVAL
 is imho enough to let application know that this memory cannot be used for
 the userptr buffer.

-EINVAL is used quite a lot already to report many different error conditions. 
-EFAULT would let application know that the issue is about the pointer address 
as opposed to the buffer index for instance.

[snip]

   + * Returns 0 on success.
   + */
   +int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long
   paddr, +  unsigned long size,
   + const struct vm_operations_struct *vm_ops,
   + void *priv)
   +{
   + int ret;
   +
   + size = min_t(unsigned long, vma-vm_end - vma-vm_start, size);
   +
   + vma-vm_page_prot = pgprot_noncached(vma-vm_page_prot);
  
  Now we're getting to the dirty part :-) Do we always want to map the
  memory uncached ?
 
 That's how it is handled by the videobuf1 and probably most of drivers that
 use physically contiguous memory. I don't want to change it right now.
 This will be a way too much for a single step. Once drivers will settle
 down on vb2 we may start thinking of adding support for CACHED vs.
 UNCACHED mappings.

OK.

  I'm not too sure about what the use cases for this function are. It seems
  to be used by the DMA coherent and CMA allocators. Are you sure they
  will always use physically contiguous memory ?
 
 Yes, both of them are designed for physically contiguous memory. I just
 noticed that the videobuf1 used the dma-contig name which is a bit better
 for this case. ;)

OK.

   + ret = remap_pfn_range(vma, vma-vm_start, paddr  PAGE_SHIFT,
   + size, vma-vm_page_prot);
   + if (ret) {
   + printk(KERN_ERR Remapping memory failed, error: %d\n, ret);
   + return ret;
   + }
   +
   + vma-vm_flags   |= VM_DONTEXPAND | VM_RESERVED;
   + vma-vm_private_data= priv;
   + vma-vm_ops = vm_ops;
   +
   + vm_ops-open(vma);
   +
   + printk(KERN_DEBUG %s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n,
   + __func__, paddr, vma-vm_start, size);
   +
   + return 0;
   +}
   +
   +/**
   + * vb2_get_userptr() - acquire an area pointed to by userspace addres
   vaddr + * @vaddr: virtual userspace address to the given area
   + *
   + * This function attempts to acquire an area mapped in the userspace
   for + * the duration of a hardware operation.
   + *
   + * Returns a virtual memory region associated with the given vaddr on
   success + * or NULL.
   + */
   +struct vm_area_struct *vb2_get_userptr(unsigned long vaddr)
   +{
   + struct mm_struct *mm = current-mm;
   + struct vm_area_struct *vma;
   + struct vm_area_struct *vma_copy;
   +
   + vma_copy = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
   + if (vma_copy == NULL)
   + return NULL;
   +
   + down_read(mm-mmap_sem);
   +
   + vma = find_vma(mm, vaddr);
   + if (!vma)
   + goto done;
   +
   + if (vma-vm_ops  vma-vm_ops-open)
   + vma-vm_ops-open(vma);
   +
   + if (vma-vm_file)
   + get_file(vma-vm_file);
  
  Could you explain what this is for ?
 
 This is called when you access physically contiguous memory from different
 device which has been earlier mmaped by the application. This way
 applications uses userptr mode with dmacontig. When doing this, you must
 ensure somehow that this memory won't be released/freed before you finish.
 This is achieved by calling open() callback and increasing the use count
 of the mmaped file. Same things happen when your application calls fork()
 and a new process gets access to your mmaped device.

Good point.

Don't you also need to pin the pages to memory with get_user_pages() ?

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message 

RE: [PATCH 2/7] v4l: videobuf2: add generic memory handling routines

2010-11-29 Thread Marek Szyprowski
Hello,

On Monday, November 29, 2010 2:41 PM Laurent Pinchart wrote:

 Hi Marek,
 
 On Monday 29 November 2010 14:24:35 Marek Szyprowski wrote:
  On Monday, November 29, 2010 10:39 AM Laurent Pinchart wrote:
   On Friday 19 November 2010 16:55:39 Marek Szyprowski wrote:
From: Pawel Osciak p.osc...@samsung.com
   
Add generic memory handling routines for userspace pointer handling,
contiguous memory verification and mapping.
   
Signed-off-by: Pawel Osciak p.osc...@samsung.com
Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
CC: Pawel Osciak pa...@osciak.com
 
 [snip]
 
+   if (ret) {
+   printk(KERN_ERR Invalid userspace address\n);
+   goto done;
+   }
+
+   *paddr = (curr_pfn  PAGE_SHIFT) + offset;
+
+   for (i = 1; i  num_pages; ++i) {
+   prev_pfn = curr_pfn;
+   vaddr += PAGE_SIZE;
+
+   ret = follow_pfn(vma, vaddr, curr_pfn);
+   if (ret || curr_pfn != prev_pfn + 1) {
+   printk(KERN_ERR Invalid userspace address\n);
+   ret = -EINVAL;
  
   I would use -EFAULT when curr_pfn != prev_pfn + 1.
 
  I don't think that this situation desires for a EFAULT error code. EINVAL
  is imho enough to let application know that this memory cannot be used for
  the userptr buffer.
 
 -EINVAL is used quite a lot already to report many different error conditions.
 -EFAULT would let application know that the issue is about the pointer address
 as opposed to the buffer index for instance.

The application will not notice it probably in this case, because a default
EFAULT handler will kill it in most of the cases ;)

snip

+/**
+ * vb2_get_userptr() - acquire an area pointed to by userspace addres
vaddr + * @vaddr:   virtual userspace address to the given area
+ *
+ * This function attempts to acquire an area mapped in the userspace
for + * the duration of a hardware operation.
+ *
+ * Returns a virtual memory region associated with the given vaddr on
success + * or NULL.
+ */
+struct vm_area_struct *vb2_get_userptr(unsigned long vaddr)
+{
+   struct mm_struct *mm = current-mm;
+   struct vm_area_struct *vma;
+   struct vm_area_struct *vma_copy;
+
+   vma_copy = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+   if (vma_copy == NULL)
+   return NULL;
+
+   down_read(mm-mmap_sem);
+
+   vma = find_vma(mm, vaddr);
+   if (!vma)
+   goto done;
+
+   if (vma-vm_ops  vma-vm_ops-open)
+   vma-vm_ops-open(vma);
+
+   if (vma-vm_file)
+   get_file(vma-vm_file);
  
   Could you explain what this is for ?
 
  This is called when you access physically contiguous memory from different
  device which has been earlier mmaped by the application. This way
  applications uses userptr mode with dmacontig. When doing this, you must
  ensure somehow that this memory won't be released/freed before you finish.
  This is achieved by calling open() callback and increasing the use count
  of the mmaped file. Same things happen when your application calls fork()
  and a new process gets access to your mmaped device.
 
 Good point.
 
 Don't you also need to pin the pages to memory with get_user_pages() ?

Nope. get_user_pages() doesn't support pfn-type memory at all (it just fails
this that case). PFN-type memory cannot be swapped out anyway so it not a
problem here.

Best regards
--
Marek Szyprowski
Samsung Poland RD Center

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/7] v4l: videobuf2: add generic memory handling routines

2010-11-29 Thread Laurent Pinchart
Hi Marek,

On Monday 29 November 2010 15:27:00 Marek Szyprowski wrote:
 Hello,
 
 On Monday, November 29, 2010 2:41 PM Laurent Pinchart wrote:
  Hi Marek,
  
  On Monday 29 November 2010 14:24:35 Marek Szyprowski wrote:
   On Monday, November 29, 2010 10:39 AM Laurent Pinchart wrote:
On Friday 19 November 2010 16:55:39 Marek Szyprowski wrote:
 From: Pawel Osciak p.osc...@samsung.com
 
 Add generic memory handling routines for userspace pointer
 handling, contiguous memory verification and mapping.
 
 Signed-off-by: Pawel Osciak p.osc...@samsung.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 CC: Pawel Osciak pa...@osciak.com
  
  [snip]
  
 + if (ret) {
 + printk(KERN_ERR Invalid userspace address\n);
 + goto done;
 + }
 +
 + *paddr = (curr_pfn  PAGE_SHIFT) + offset;
 +
 + for (i = 1; i  num_pages; ++i) {
 + prev_pfn = curr_pfn;
 + vaddr += PAGE_SIZE;
 +
 + ret = follow_pfn(vma, vaddr, curr_pfn);
 + if (ret || curr_pfn != prev_pfn + 1) {
 + printk(KERN_ERR Invalid userspace address\n);
 + ret = -EINVAL;

I would use -EFAULT when curr_pfn != prev_pfn + 1.
   
   I don't think that this situation desires for a EFAULT error code.
   EINVAL is imho enough to let application know that this memory cannot
   be used for the userptr buffer.
  
  -EINVAL is used quite a lot already to report many different error
  conditions. -EFAULT would let application know that the issue is about
  the pointer address as opposed to the buffer index for instance.
 
 The application will not notice it probably in this case, because a default
 EFAULT handler will kill it in most of the cases ;)

Will it ? Where ? ioctls can return -EFAULT.

 +/**
 + * vb2_get_userptr() - acquire an area pointed to by userspace
 addres vaddr + * @vaddr:  virtual userspace address to the given
 area + *
 + * This function attempts to acquire an area mapped in the
 userspace for + * the duration of a hardware operation.
 + *
 + * Returns a virtual memory region associated with the given vaddr
 on success + * or NULL.
 + */
 +struct vm_area_struct *vb2_get_userptr(unsigned long vaddr)
 +{
 + struct mm_struct *mm = current-mm;
 + struct vm_area_struct *vma;
 + struct vm_area_struct *vma_copy;
 +
 + vma_copy = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
 + if (vma_copy == NULL)
 + return NULL;
 +
 + down_read(mm-mmap_sem);
 +
 + vma = find_vma(mm, vaddr);
 + if (!vma)
 + goto done;
 +
 + if (vma-vm_ops  vma-vm_ops-open)
 + vma-vm_ops-open(vma);
 +
 + if (vma-vm_file)
 + get_file(vma-vm_file);

Could you explain what this is for ?
   
   This is called when you access physically contiguous memory from
   different device which has been earlier mmaped by the application.
   This way applications uses userptr mode with dmacontig. When doing
   this, you must ensure somehow that this memory won't be released/freed
   before you finish. This is achieved by calling open() callback and
   increasing the use count of the mmaped file. Same things happen when
   your application calls fork() and a new process gets access to your
   mmaped device.
  
  Good point.
  
  Don't you also need to pin the pages to memory with get_user_pages() ?
 
 Nope. get_user_pages() doesn't support pfn-type memory at all (it just
 fails this that case). PFN-type memory cannot be swapped out anyway so it
 not a problem here.

But vb2_get_userptr() can be used on non-PFN memory, can't it ?

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 2/7] v4l: videobuf2: add generic memory handling routines

2010-11-29 Thread Marek Szyprowski
Hello,

On Monday, November 29, 2010 3:37 PM Laurent Pinchart wrote:

 On Monday 29 November 2010 15:27:00 Marek Szyprowski wrote:
  Hello,
 
  On Monday, November 29, 2010 2:41 PM Laurent Pinchart wrote:
   Hi Marek,
  
   On Monday 29 November 2010 14:24:35 Marek Szyprowski wrote:
On Monday, November 29, 2010 10:39 AM Laurent Pinchart wrote:
 On Friday 19 November 2010 16:55:39 Marek Szyprowski wrote:
  From: Pawel Osciak p.osc...@samsung.com
 
  Add generic memory handling routines for userspace pointer
  handling, contiguous memory verification and mapping.
 
  Signed-off-by: Pawel Osciak p.osc...@samsung.com
  Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
  Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
  CC: Pawel Osciak pa...@osciak.com
  
   [snip]
  
  +   if (ret) {
  +   printk(KERN_ERR Invalid userspace address\n);
  +   goto done;
  +   }
  +
  +   *paddr = (curr_pfn  PAGE_SHIFT) + offset;
  +
  +   for (i = 1; i  num_pages; ++i) {
  +   prev_pfn = curr_pfn;
  +   vaddr += PAGE_SIZE;
  +
  +   ret = follow_pfn(vma, vaddr, curr_pfn);
  +   if (ret || curr_pfn != prev_pfn + 1) {
  +   printk(KERN_ERR Invalid userspace address\n);
  +   ret = -EINVAL;

 I would use -EFAULT when curr_pfn != prev_pfn + 1.
   
I don't think that this situation desires for a EFAULT error code.
EINVAL is imho enough to let application know that this memory cannot
be used for the userptr buffer.
  
   -EINVAL is used quite a lot already to report many different error
   conditions. -EFAULT would let application know that the issue is about
   the pointer address as opposed to the buffer index for instance.
 
  The application will not notice it probably in this case, because a default
  EFAULT handler will kill it in most of the cases ;)
 
 Will it ? Where ? ioctls can return -EFAULT.

Ok. You are right. I mixed something. Please ignore my previous comment.

  +/**
  + * vb2_get_userptr() - acquire an area pointed to by userspace
  addres vaddr + * @vaddr:virtual userspace address to the given
  area + *
  + * This function attempts to acquire an area mapped in the
  userspace for + * the duration of a hardware operation.
  + *
  + * Returns a virtual memory region associated with the given vaddr
  on success + * or NULL.
  + */
  +struct vm_area_struct *vb2_get_userptr(unsigned long vaddr)
  +{
  +   struct mm_struct *mm = current-mm;
  +   struct vm_area_struct *vma;
  +   struct vm_area_struct *vma_copy;
  +
  +   vma_copy = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
  +   if (vma_copy == NULL)
  +   return NULL;
  +
  +   down_read(mm-mmap_sem);
  +
  +   vma = find_vma(mm, vaddr);
  +   if (!vma)
  +   goto done;
  +
  +   if (vma-vm_ops  vma-vm_ops-open)
  +   vma-vm_ops-open(vma);
  +
  +   if (vma-vm_file)
  +   get_file(vma-vm_file);

 Could you explain what this is for ?
   
This is called when you access physically contiguous memory from
different device which has been earlier mmaped by the application.
This way applications uses userptr mode with dmacontig. When doing
this, you must ensure somehow that this memory won't be released/freed
before you finish. This is achieved by calling open() callback and
increasing the use count of the mmaped file. Same things happen when
your application calls fork() and a new process gets access to your
mmaped device.
  
   Good point.
  
   Don't you also need to pin the pages to memory with get_user_pages() ?
 
  Nope. get_user_pages() doesn't support pfn-type memory at all (it just
  fails this that case). PFN-type memory cannot be swapped out anyway so it
  not a problem here.
 
 But vb2_get_userptr() can be used on non-PFN memory, can't it ?

I thought that this function is used only by dma-coherent and cma allocators.
dma-sg and iommu allocators will definitely call get_user_pages().

Best regards
--
Marek Szyprowski
Samsung Poland RD Center

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/7] v4l: videobuf2: add generic memory handling routines

2010-11-29 Thread Laurent Pinchart
Hi Marek,

On Monday 29 November 2010 16:13:17 Marek Szyprowski wrote:
 On Monday, November 29, 2010 3:37 PM Laurent Pinchart wrote:
  On Monday 29 November 2010 15:27:00 Marek Szyprowski wrote:
   On Monday, November 29, 2010 2:41 PM Laurent Pinchart wrote:
On Monday 29 November 2010 14:24:35 Marek Szyprowski wrote:
 On Monday, November 29, 2010 10:39 AM Laurent Pinchart wrote:
  On Friday 19 November 2010 16:55:39 Marek Szyprowski wrote:
   From: Pawel Osciak p.osc...@samsung.com
   
   Add generic memory handling routines for userspace pointer
   handling, contiguous memory verification and mapping.
   
   Signed-off-by: Pawel Osciak p.osc...@samsung.com
   Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
   Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
   CC: Pawel Osciak pa...@osciak.com

[snip]

   + if (ret) {
   + printk(KERN_ERR Invalid userspace address\n);
   + goto done;
   + }
   +
   + *paddr = (curr_pfn  PAGE_SHIFT) + offset;
   +
   + for (i = 1; i  num_pages; ++i) {
   + prev_pfn = curr_pfn;
   + vaddr += PAGE_SIZE;
   +
   + ret = follow_pfn(vma, vaddr, curr_pfn);
   + if (ret || curr_pfn != prev_pfn + 1) {
   + printk(KERN_ERR Invalid userspace address\n);
   + ret = -EINVAL;
  
  I would use -EFAULT when curr_pfn != prev_pfn + 1.
 
 I don't think that this situation desires for a EFAULT error code.
 EINVAL is imho enough to let application know that this memory
 cannot be used for the userptr buffer.

-EINVAL is used quite a lot already to report many different error
conditions. -EFAULT would let application know that the issue is
about the pointer address as opposed to the buffer index for
instance.
   
   The application will not notice it probably in this case, because a
   default EFAULT handler will kill it in most of the cases ;)
  
  Will it ? Where ? ioctls can return -EFAULT.
 
 Ok. You are right. I mixed something. Please ignore my previous comment.
 
   +/**
   + * vb2_get_userptr() - acquire an area pointed to by userspace
   addres vaddr + * @vaddr:  virtual userspace address to the given
   area + *
   + * This function attempts to acquire an area mapped in the
   userspace for + * the duration of a hardware operation.
   + *
   + * Returns a virtual memory region associated with the given
   vaddr on success + * or NULL.
   + */
   +struct vm_area_struct *vb2_get_userptr(unsigned long vaddr)
   +{
   + struct mm_struct *mm = current-mm;
   + struct vm_area_struct *vma;
   + struct vm_area_struct *vma_copy;
   +
   + vma_copy = kmalloc(sizeof(struct vm_area_struct),
   GFP_KERNEL); +if (vma_copy == NULL)
   + return NULL;
   +
   + down_read(mm-mmap_sem);
   +
   + vma = find_vma(mm, vaddr);
   + if (!vma)
   + goto done;
   +
   + if (vma-vm_ops  vma-vm_ops-open)
   + vma-vm_ops-open(vma);
   +
   + if (vma-vm_file)
   + get_file(vma-vm_file);
  
  Could you explain what this is for ?
 
 This is called when you access physically contiguous memory from
 different device which has been earlier mmaped by the application.
 This way applications uses userptr mode with dmacontig. When doing
 this, you must ensure somehow that this memory won't be
 released/freed before you finish. This is achieved by calling
 open() callback and increasing the use count of the mmaped file.
 Same things happen when your application calls fork() and a new
 process gets access to your mmaped device.

Good point.

Don't you also need to pin the pages to memory with get_user_pages()
?
   
   Nope. get_user_pages() doesn't support pfn-type memory at all (it just
   fails this that case). PFN-type memory cannot be swapped out anyway so
   it not a problem here.
  
  But vb2_get_userptr() can be used on non-PFN memory, can't it ?
 
 I thought that this function is used only by dma-coherent and cma
 allocators. dma-sg and iommu allocators will definitely call
 get_user_pages().

Then it should probably be renamed to vb2_get_pfn_user_pages().

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/7] v4l: videobuf2: add generic memory handling routines

2010-11-19 Thread Marek Szyprowski
From: Pawel Osciak p.osc...@samsung.com

Add generic memory handling routines for userspace pointer handling,
contiguous memory verification and mapping.

Signed-off-by: Pawel Osciak p.osc...@samsung.com
Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
CC: Pawel Osciak pa...@osciak.com
---
 drivers/media/video/Kconfig|3 +
 drivers/media/video/Makefile   |1 +
 drivers/media/video/videobuf2-memops.c |  199 
 include/media/videobuf2-memops.h   |   31 +
 4 files changed, 234 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/videobuf2-memops.c
 create mode 100644 include/media/videobuf2-memops.h

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index fef6a14..83ce858 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -52,6 +52,9 @@ config V4L2_MEM2MEM_DEV
 config VIDEOBUF2_CORE
tristate
 
+config VIDEOBUF2_MEMOPS
+   tristate
+
 #
 # Multimedia Video device configuration
 #
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 77c4f85..a97a2a0 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
 obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
 
 obj-$(CONFIG_VIDEOBUF2_CORE)   += videobuf2-core.o
+obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
 
 obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
 
diff --git a/drivers/media/video/videobuf2-memops.c 
b/drivers/media/video/videobuf2-memops.c
new file mode 100644
index 000..67ebdff
--- /dev/null
+++ b/drivers/media/video/videobuf2-memops.c
@@ -0,0 +1,199 @@
+/*
+ * videobuf2-memops.c - generic memory handling routines for videobuf2
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak p.osc...@samsung.com
+ *Marek Szyprowski m.szyprow...@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#include linux/slab.h
+#include linux/module.h
+#include linux/dma-mapping.h
+#include linux/vmalloc.h
+#include linux/cma.h
+#include linux/mm.h
+#include linux/sched.h
+#include linux/file.h
+
+#include media/videobuf2-core.h
+
+/**
+ * vb2_contig_verify_userptr() - verify contiguity of a userspace-mapped memory
+ * @vma:   virtual memory region which maps the physical memory
+ * to be verified
+ * @vaddr: starting virtual address of the area to be verified
+ * @size:  size of the area to be verified
+ * @paddr: will return physical address for the given vaddr
+ *
+ * This function will go through memory area of size size mapped at vaddr and
+ * verify that the underlying physical pages are contiguous.
+ *
+ * Returns 0 on success and a physical address to the memory pointed
+ * to by vaddr in paddr.
+ */
+int vb2_contig_verify_userptr(struct vm_area_struct *vma,
+   unsigned long vaddr, unsigned long size,
+   unsigned long *paddr)
+{
+   struct mm_struct *mm = current-mm;
+   unsigned long offset;
+   unsigned long vma_size;
+   unsigned long curr_pfn, prev_pfn;
+   unsigned long num_pages;
+   int ret = -EINVAL;
+   unsigned int i;
+
+   offset = vaddr  ~PAGE_MASK;
+
+   down_read(mm-mmap_sem);
+
+   vma = find_vma(mm, vaddr);
+   if (!vma) {
+   printk(KERN_ERR Invalid userspace address\n);
+   goto done;
+   }
+
+   vma_size = vma-vm_end - vma-vm_start;
+
+   if (size  vma_size - offset) {
+   printk(KERN_ERR Region too small\n);
+   goto done;
+   }
+   num_pages = (size + offset)  PAGE_SHIFT;
+
+   ret = follow_pfn(vma, vaddr, curr_pfn);
+   if (ret) {
+   printk(KERN_ERR Invalid userspace address\n);
+   goto done;
+   }
+
+   *paddr = (curr_pfn  PAGE_SHIFT) + offset;
+
+   for (i = 1; i  num_pages; ++i) {
+   prev_pfn = curr_pfn;
+   vaddr += PAGE_SIZE;
+
+   ret = follow_pfn(vma, vaddr, curr_pfn);
+   if (ret || curr_pfn != prev_pfn + 1) {
+   printk(KERN_ERR Invalid userspace address\n);
+   ret = -EINVAL;
+   break;
+   }
+   }
+
+done:
+   up_read(mm-mmap_sem);
+   return ret;
+}
+
+/**
+ * vb2_mmap_pfn_range() - map physical pages to userspace
+ * @vma:   virtual memory region for the mapping
+ * @paddr: starting physical address of the memory to be mapped
+ * @size:  size of the memory to be mapped
+ * @vm_ops:vm operations to be assigned to the created area
+ * @priv:  private data to be associated with the area
+ *
+ * Returns 0 on success.
+ */
+int 

[PATCH 2/7] v4l: videobuf2: add generic memory handling routines

2010-11-17 Thread Marek Szyprowski
From: Pawel Osciak p.osc...@samsung.com

Add generic memory handling routines for userspace pointer handling,
contiguous memory verification and mapping.

Signed-off-by: Pawel Osciak p.osc...@samsung.com
Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
CC: Pawel Osciak pa...@osciak.com
---
 drivers/media/video/Kconfig|3 +
 drivers/media/video/Makefile   |1 +
 drivers/media/video/videobuf2-memops.c |  199 
 include/media/videobuf2-memops.h   |   31 +
 4 files changed, 234 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/videobuf2-memops.c
 create mode 100644 include/media/videobuf2-memops.h

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index fef6a14..83ce858 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -52,6 +52,9 @@ config V4L2_MEM2MEM_DEV
 config VIDEOBUF2_CORE
tristate
 
+config VIDEOBUF2_MEMOPS
+   tristate
+
 #
 # Multimedia Video device configuration
 #
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 77c4f85..a97a2a0 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
 obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
 
 obj-$(CONFIG_VIDEOBUF2_CORE)   += videobuf2-core.o
+obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
 
 obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
 
diff --git a/drivers/media/video/videobuf2-memops.c 
b/drivers/media/video/videobuf2-memops.c
new file mode 100644
index 000..67ebdff
--- /dev/null
+++ b/drivers/media/video/videobuf2-memops.c
@@ -0,0 +1,199 @@
+/*
+ * videobuf2-memops.c - generic memory handling routines for videobuf2
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak p.osc...@samsung.com
+ *Marek Szyprowski m.szyprow...@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#include linux/slab.h
+#include linux/module.h
+#include linux/dma-mapping.h
+#include linux/vmalloc.h
+#include linux/cma.h
+#include linux/mm.h
+#include linux/sched.h
+#include linux/file.h
+
+#include media/videobuf2-core.h
+
+/**
+ * vb2_contig_verify_userptr() - verify contiguity of a userspace-mapped memory
+ * @vma:   virtual memory region which maps the physical memory
+ * to be verified
+ * @vaddr: starting virtual address of the area to be verified
+ * @size:  size of the area to be verified
+ * @paddr: will return physical address for the given vaddr
+ *
+ * This function will go through memory area of size size mapped at vaddr and
+ * verify that the underlying physical pages are contiguous.
+ *
+ * Returns 0 on success and a physical address to the memory pointed
+ * to by vaddr in paddr.
+ */
+int vb2_contig_verify_userptr(struct vm_area_struct *vma,
+   unsigned long vaddr, unsigned long size,
+   unsigned long *paddr)
+{
+   struct mm_struct *mm = current-mm;
+   unsigned long offset;
+   unsigned long vma_size;
+   unsigned long curr_pfn, prev_pfn;
+   unsigned long num_pages;
+   int ret = -EINVAL;
+   unsigned int i;
+
+   offset = vaddr  ~PAGE_MASK;
+
+   down_read(mm-mmap_sem);
+
+   vma = find_vma(mm, vaddr);
+   if (!vma) {
+   printk(KERN_ERR Invalid userspace address\n);
+   goto done;
+   }
+
+   vma_size = vma-vm_end - vma-vm_start;
+
+   if (size  vma_size - offset) {
+   printk(KERN_ERR Region too small\n);
+   goto done;
+   }
+   num_pages = (size + offset)  PAGE_SHIFT;
+
+   ret = follow_pfn(vma, vaddr, curr_pfn);
+   if (ret) {
+   printk(KERN_ERR Invalid userspace address\n);
+   goto done;
+   }
+
+   *paddr = (curr_pfn  PAGE_SHIFT) + offset;
+
+   for (i = 1; i  num_pages; ++i) {
+   prev_pfn = curr_pfn;
+   vaddr += PAGE_SIZE;
+
+   ret = follow_pfn(vma, vaddr, curr_pfn);
+   if (ret || curr_pfn != prev_pfn + 1) {
+   printk(KERN_ERR Invalid userspace address\n);
+   ret = -EINVAL;
+   break;
+   }
+   }
+
+done:
+   up_read(mm-mmap_sem);
+   return ret;
+}
+
+/**
+ * vb2_mmap_pfn_range() - map physical pages to userspace
+ * @vma:   virtual memory region for the mapping
+ * @paddr: starting physical address of the memory to be mapped
+ * @size:  size of the memory to be mapped
+ * @vm_ops:vm operations to be assigned to the created area
+ * @priv:  private data to be associated with the area
+ *
+ * Returns 0 on success.
+ */
+int